Command Pattern
태그 :
- 개념
- - 명령을 클래스로 만든다
I. 의도
요청 자체를 객체화해 클라이언트에 패러미터로 넘길 수 있게 한다
정의: 명령을 클래스로 만든다.
II. 활용
- 수행할 행위 자체를 객체로 패러미터화하고자 할 때 – 절차적 프로그래밍 방식의 callback()함수와 동일
- 서로 다른 시간에 요청을 명시하고, 저장하고, 수행할 수 있다. Command 객체는 원래의 요청과는 다른 생명주기 가짐
- 명령어 객체 자체에 실행 취소에 필요한 상태를 저장할 수 있다
- 변경 과정에 대한 로그를 남겨두면 시스템 고장시 원상태로 복구가 가능하다
- 기본적인 오퍼레이션 조합으로 고난도의 오퍼레이션 구성 가능 – 트랜잭션 모델링 가능
III. 결과
- command는 오퍼레이션을 호출하는 객체와 오퍼레이션 수행 방법을 구현하는 객체를 분리한다
- command 자체도 클래스로서 다른 객체와 같은 방식으로 조작되고 확장될 수 있다
- 명령어를 조합해서 다른 명령어를 만들 수 있다 – composite 패턴을 이용해 여러 명령어 구성 가능
- 새로운 명령어 추가가 쉽다 – 클래스 변경없이 새로운 명령어에 대한 클래스만 정의하면 된다
관련 패턴: MacroCommand를 구현하고자 할때 Composite 패턴을 사용했다. 취소를 처리할 때 객체의 상태를 관리하고자 한다면 Memento를 사용해야 한다. 또 명령어가 처리되어 처리된 이력 리스트에 저장되기 전에 명령어를 복사해야 한다면 Prototype을 사용하면 된다.
Command |
오퍼레이션 수행에 필요한 인터페이스 선언 |
ConcreteCommand |
|
Client |
- ConcreateCommand 객체를 생성하고 그것의 receiver를 세팅함 |
Invoker |
|
Receiver |
- 요청을 처리하는데 관련된 오퍼레이션 수행방법을 알고 있음 |
소스코드
사례
- 게시판의 쓰기, 삭제, 수정 등의 Action을 캡슐화
- 그림판 프로그램에서 그리기, 지우기, 배경색 지정, 필터 적용 등을 캡슐화
- 리모콘 기능 구현
/*the Invoker class*/
public class Switch {
private Command flipUpCommand;
private Command flipDownCommand;
public Switch(Command flipUpCmd,Command flipDownCmd){
this.flipUpCommand=flipUpCmd;
this.flipDownCommand=flipDownCmd;
}
public void flipUp(){
flipUpCommand.execute();
}
public void flipDown(){
flipDownCommand.execute();
}
}
/*Receiver class*/
public class Light{
public Light(){ }
public void turnOn(){
System.out.println("The light is on");
}
public void turnOff(){
System.out.println("The light is off");
}
}
/*the Command interface*/
public interface Command{
void execute();
}
/*the Command for turning on the light*/
public class TurnOnLightCommand implements Command{
private Light theLight;
public TurnOnLightCommand(Light light){
this.theLight=light;
}
public void execute(){
theLight.turnOn();
}
}
/*the Command for turning off the light*/
public class TurnOffLightCommand implements Command{
private Light theLight;
public TurnOffLightCommand(Light light){
this.theLight=light;
}
public void execute(){
theLight.turnOff();
}
}
/*The test class*/
public class TestCommand{
public static void main(String[] args){
Light l=new Light();
Command switchUp=new TurnOnLightCommand(l);
Command switchDown=new TurnOffLightCommand(l);
Switch s=new Switch(switchUp,switchDown);
s.flipUp();
s.flipDown();
}
}