일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 다자인패턴
- cache
- 전략패턴
- 객체지향
- 클래스다이어그램
- 디자인패턴
- Programming
- 자바
- 웹개발
- 집합관계
- 의존관계
- 연관관계
- 프로그래밍
- jpa
- backend
- 봇
- OOP
- java
- Web
- Spring
- 백엔드
- 웹
- Sprign
- 코딩
- redis
- 개발
- IT
- 서버개발
- spring data jpa
- caching
- Today
- Total
괴발나라
[GOF] 커맨드 패턴으로 우콩 만들기 🐒 본문
오늘은 커맨드 패턴에 대해 알아보겠습니다.
커맨드 패턴은 이벤트를 발생시키는 객체(Invoker)와
그 이벤트를 받는 객체(Reciever)로 구성되어 있습니다.
가령 어떤 버튼을 클릭했을때 전등이 켜지거나 꺼진다면,
그 버튼은 "클릭됨" 이라는 이벤트를 발생시키고
전등은 그 이벤트를 수신하여 켜지거나 꺼지겠죠?
여기서 버튼은 Invoker, 전등은 Reciever가 됩니다.
커맨드 패턴은 이런 기능을 SOLID원칙을 지키며 구현할 수 있도록 해줍니다.
오공으로 미니언 처치하기
LOL(리그오브레전드)이라는 게임을 아시나요?
LOL에서는 게이머가 한 챔피언(캐릭터)을 골라
미니언(적)을 처치하며 챔피언의 레벨을 올릴 수 있습니다.
챔피언이 Invoker이고, 미니언은 Reciever라고 해봅시다.
챔피언이 "공격"이라는 이벤트를 발생시키면,
미니언의 체력은 줄어듭니다.
이제 코드로 구현해볼 것입니다.
챔피언중에는 "오공"이라는 캐릭터가 있는데요,
손오공이라고 생각하시면 됩니다.
그럼 한번 이 오공 챔피언을 클래스로 만들어보겠습니다.
interface Champion {
void attack(Minion minion);
}
class Wukong implements Champion {
@Override
public void attack(Minion minion) {
System.out.println("기본 공격!");
minion.decreaseHp(10); // 미니언 체력 5 감소
}
}
Champion 인터페이스를 만든 이유는 챔피언은 오공만이 아닌 여러개가 있기 때문입니다.
그러면 미니언도 클래스로 만들어 봅시다.
class Minion {
private int hp;
Minion(int hp){
this.hp = hp;
}
void decreaseHp(int amount) {
this.hp -= amount;
System.out.println("미니언의 hp가 " + this.hp + "가 되었습니다.");
}
}
공격 시 미니언의 체력(hp)를 줄여야 하기 때문에 decreaseHp라는 메서드를 만들었습니다.
현재 오공은 기본 공격만 할 수 있습니다.
더 데미지가 높은 "근두운 급습(W)" 스킬로 공격하게 하려면 다음과 같이 변경해야합니다.
class Wukong implements Champion {
@Override
public void attack(Minion minion) {
//System.out.println("기본 공격!");
//minion.decreaseHp(5);
System.out.println("근두운 급습!");
minion.decreaseHp(20); // 미니언 체력 20 감소
}
}
"파쇄격(Q)"로 공격하려면 또 위와 같은 방식으로 변경해줘야 합니다.
공격 기술을 변경하려면 코드를 주석처리하고 새로 작성하는 작업을 반복해야 합니다.
심지어 실행 시 동적으로 공격 기술을 바꿀 수 도 없습니다.
커맨드 패턴을 이용해서 게이머가 원하는 공격 기술을 자유롭게 선택할 수 있도록 해줍시다.
커맨드 패턴으로 개선시키기
먼저 공격 커맨드 인터페이스를 만들어 공격 기능을 추상화시킵니다.
interface AttackCommand {
void execute();
}
// 기본 공격 커맨드
class BasicAttackCommand implements AttackCommand {
private Minion minion;
BasicAttackCommand(Minion minion) {
this.minion = minion;
}
@Override
public void execute() {
System.out.println("기본 공격!");
this.minion.decreaseHp(5);
}
}
// 파쇄격 공격 커맨드
class QAttackCommand implements AttackCommand {
private Minion minion;
QAttackCommand(Minion minion) {
this.minion = minion;
}
@Override
public void execute() {
System.out.println("파쇄격!");
this.minion.decreaseHp(10);
}
}
// 근두운 급습 공격 커맨드
class WAttackCommand implements AttackCommand {
private Minion minion;
WAttackCommand(Minion minion) {
this.minion = minion;
}
@Override
public void execute() {
System.out.println("근두운 급습!");
this.minion.decreaseHp(20);
}
}
조금 복잡해졌지만,
충분히 공격 기능을 인터페이스로 추상화할 가치가 있습니다.
오공 클래스의 코드를 보면 아실겁니다.
class Wukong implements Champion {
private AttackCommand attackCommand;
public void setAttackCommand(AttackCommand attackCommand) {
this.attackCommand = attackCommand; // 공격 커맨드를 외부에서 선택합니다.
}
@Override
public void attack() {
this.attackCommand.execute(); // 공격 커맨드에게 기능을 위임만 하고 끝납니다.
}
}
게이머가 공격 기능을 자유롭게 변경할 수 있게 되었습니다.
직접 공격 기능을 변경해가며 미니언을 처치해봅시다!
public class Client {
public static void main(String[] args) {
Minion minion = new Minion(100); // 미니언의 체력은 100입니다.
AttackCommand click = new BasicAttackCommand(minion); // 기본 공격
AttackCommand Q = new QAttackCommand(minion); // 파쇄격
AttackCommand W = new WAttackCommand(minion); // 근두운 급습
Wukong wukong = new Wukong();
wukong.setAttackCommand(click);
wukong.attack();
// 기본 공격!
// 미니언의 hp가 95가 되었습니다.
wukong.setAttackCommand(Q);
wukong.attack();
// 파쇄격!
// 미니언의 hp가 85가 되었습니다.
wukong.setAttackCommand(W);
wukong.attack();
// 근두운 급습!
// 미니언의 hp가 65가 되었습니다.
}
}
다른 챔피언을 만들어 새로운 공격 커맨드를 작성해도
매우 재밌는 작업이 될 듯 합니다.
감사합니다.
'도서 > JAVA 객체지향 디자인패턴' 카테고리의 다른 글
[GOF] 스테이트 패턴으로 슈팅게임 만들기 🔫 (0) | 2022.02.05 |
---|---|
[GOF] 전략 패턴으로 비행기 게임 만들기 🛫🛬 (0) | 2022.02.04 |
디자인 패턴이 뭐냐 🤔 (0) | 2022.02.03 |
클래스 다이어그램의 집합관계 (0) | 2022.02.01 |
연관 관계와 의존 관계의 차이 (5) | 2022.02.01 |