07. Command Pattern

요구사항(요청, 명령)을 객체로 캡슐화 시킨다.
다른 요구사항을 지닌 클라이언트를 매개변수화 시킬 수 있고, 요구사항을 큐에 넣거나 로그로 남길 수 있으며 작업 취소 기능을 지원할 수도 있다.
행동과 리시버를 한 객체에 집어넣고, execute()라는 메소드 하나만 외부에 공개한다.

Problem

사용하려는 객체가 많고, API가 서로 다른 경우 번거로움이 존재한다.

Solution

  1. Command: receiver를 알고 있고, Reciever의 메소드를 호출한다.
  2. Client: 커맨드 객체 생성
  3. Receiver: 명령을 수행하는 객체 ex) TV 등 디바이스
  4. ConcreteCommand: 어떤 Reciver를 실행할 지 연결하고 특정 액션을 한다.
  5. Invoker: 실제 명령을 실행하는 것(트리거)

Invoker(버튼 클릭하면 기능 수행) - Command(연결, wrapper 역할 즉, 감춰줌) - Receiver(실제 객체)

예시1 - 객체마을 식당

  1. Order
  • 주문한 메뉴를 요구하는 역할
  • 웨이트런이 계산대 또는 다른 웨이트런에게 전달한다.
  1. Waitron
  • 주문서를 받고, 주문서를 전달하고 orderUp() 호출 → 식사 준비를 시키는 역할
  • Order에 무슨 내용이 있는지, 누가 식사를 준비하는지 알 필요 없다.
  • takeOrder() 메소드 포함 (여러 Client가 여러 Order를 전달)
  1. Chef
  • 식사를 준비하는 방법을 알고 있다.
  • 웨이트런은 주문서에 있는 orderUp()을 호출하고 Chef는 Order로부터 할 일을 전달 받음
  • 웨이트런과 분리되어 있다.

→ 요구, 처리 객체를 분리하고 있다.

예시2 - 리모컨

Command interface
//커맨드 객체는 모두 같은 인터페이스를 구현해야 한다.
public interface Command {
	public void execute();
}
Command class 구현
public class LightOnCommand implements Command{
    Light light;

    public LightOnCommand(Light light) {
        this.light = light;
    }

    @Override
    public void execute() {
        light.on();
    }
    //command.excute로 실제 객체를 실행 해줌

}
버튼이 하나 뿐인 리모컨이라면?
public class SimpleRemoteControl {
    Command slot;

    public SimpleRemoteControl() {
    }

    public void setCommand(Command command){
        slot = command;
    }

    public void buttonWasPressed(){
        slot.execute();
    }
}
다른 기능이 추가된다면?
  • command를 구현한 클래스를 Control의 setter를 이용해 변경해서 buttonWasPressde() 함수를 호출해준다.

좋은 웹페이지 즐겨찾기