커맨드 패턴
요청 내역을 객체로 캡슐화 해서 객체를 서로 다른 요청 내역에 따라 매개변수화할 수 있습니다.
이러면 요청을 큐에 저장하거나 로그로 기록하거나 작업 취소 기능을 사용할 수 있습니다.
즉, 요청하는 객체와 요챙을 수행하는 객체를 분리할 수 있습니다.
저는 여러 명령들을 추상화해서 클래스로 정의하고 객체로 만들어서 사용하는 패턴이라고 말할 수 있을 거 같습니다.
커맨드 패턴의 구조
- Command (명령)은 작업을 수행하는 인터페이스
- ConcreteCommand (구체적 명령)는 실제 작업을 구현한 클래스(예제에서의 DarkSightOnCommand, LuckySeven 등)
- Invoker (호출자)는 Command 객체를 실행하는 주체 (예제에서의 SkillUser)
- Receiver (수신자)는 실제 작업을 수행하는 객체로, ConcreteCommand가 이 객체에 대한 명령을 포함하고 있습니다. (예제에서의 GameCharacter)
장점
- 새로운 command을 추가하거나 기존 command를 수정할 때 코드의 변화를 최소화한다.
- 클라이언트와 리시버를 분리하여 클라이언트가 리시버의 세부사항을 몰라도 된다.
단점
- command가 많아질 경우 클래스의 수도 증가할 수 있다.
- 간단한 상황일 경우 오히려 커맨드 패턴이 복잡할 수 있다.
커맨드 패턴 구현
public interface Command {
void execute();
void cancel();
}
public class DarkSightOnCommand implements Command {
private GameCharacter character;
public DarkSightOnCommand(GameCharacter character) {
this.character = character;
}
@Override
public void execute(){
character.useSkill("다크사이트", 10);
}
}
public class DarkSightOffCommand implements Command {
private GameCharacter character;
public DarkSightOffCommand(GameCharacter character) {
this.character = character;
}
@Override
public void execute() {
}
@Override
public void cancel() {
character.cancelSkill("다크사이트");
}
}
public class LuckySevenCommand implements Command {
private GameCharacter character;
public LuckySevenCommand(GameCharacter character) {
this.character = character;
}
public void execute() {
character.useSkill("럭키세븐", 35);
}
}
public class HasteCommand implements Command {
private GameCharacter character;
public HasteCommand(GameCharacter character) {
this.character = character;
}
@Override
public void execute() {
character.useSkill("헤이스트", 10);
}
}
public class GameCharacter {
int mana;
public GameCharacter(int fullMana) {
this.mana = fullMana;
}
public void useSkill(String skillName, int requiredMana) {
if (mana >= requiredMana) {
System.out.println(skillName + "!");
mana -= requiredMana;
} else {
System.out.println(skillName + "를 사용할 마나가 부족합니다.");
}
}
}
public class SkillUser {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void useSkill() {
command.execute();
}
public void cancelSkill() {
command.cancel();
}
}
public class Test {
public static void main(String[] args) throws InterruptedException {
// 게임 캐릭터 생성
GameCharacter character = new GameCharacter(50);
// 커맨드 객체 생성
Command luckySeven = new LuckySevenCommand(character);
Command darkSightOn = new DarkSightOnCommand(character);
Command darkSightOff = new DarkSightOffCommand(character);
Command haste = new HasteCommand(character);
// Invoker 객체 생성
SkillUser skillUser = new SkillUser();
// 스킬 사용
skillUser.setCommand(luckySeven);
skillUser.useSkill();
skillUser.setCommand(darkSightOn);
skillUser.useSkill();
Thread.sleep(1000);
skillUser.setCommand(darkSightOff);
skillUser.cancelSkill();
skillUser.setCommand(haste);
skillUser.useSkill();
}
}
// 럭키세븐!
// 다크사이트!
// 다크사이트 OFF
// 헤이스트를 사용할 마나가 부족합니다.
'개발 도서' 카테고리의 다른 글
디자인 패턴 - 템플릿 메소드 패턴 (0) | 2023.12.16 |
---|---|
디자인 패턴 - 어댑터 패턴과 퍼사드 패턴 (0) | 2023.12.12 |
디자인 패턴 - 싱글톤 패턴 (0) | 2023.12.04 |
디자인 패턴 - 팩토리 메서드 패턴, 추상 팩토리 패턴 (1) | 2023.12.02 |
디자인 패턴 - 데코레이터 패턴 (0) | 2023.11.28 |