Post

커맨드 패턴과 실사용 예제

명령(Command) 패턴

요청받은 일을 누가, 어떻게 처리하는지 알 수 없을 때 요청 자체를 캡슐화함으로써 서로 다른 요청 내역에 따라 매개변수화할 수 있다.

USE-CASE

음식을 주문받고 이를 요리하는 요리사가 있다고 하자. 요리사는 주문을 받아 요리를 하지만, 웨이터는 요리사가 누구인지, 어떻게 요리를 하는지 알 수 없다. 단지 웨이터는 주문서를 카운터에 전달한다. 이처럼 요청받은 연산이 무엇이며, 이를 처리할 객체가 누구인지에 대한 정보 없이 임의의 객체에 메세지를 보내야 할 때가 간간이 있다. 이때 명령 패턴을 사용하면 된다.

명령 패턴의 구성

  • Command(주문) : 연산 수행에 필요한 인터페이스
  • ConcreteCommand() : 실제 연산을 수행하는 클래스
  • Client : ConcreteCommand 객체를 생성
  • Invoker : ConcreateCommand의 연산을 수행하도록 요청
  • Receiver : 요청에 관련된 연산 수행을 담당

구현

  1. 커맨드 인터페이스 구현
    1
    2
    3
    
    public interface Order {
      void execute();
    }
    
  2. 커맨드 클래스 구현
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    public class CookOrder implements Order {
    
     private Chief chief; // Receiver를 ConcreteCommand에 포함시킨다. 
     private String order;
    
     public CookOrder(Chief chief, String order) {
         this.chief = chief;
         this.order = order;
     }
    
     @Override
     public void execute() {
         chief.cookOrder(order);
     }
    }
    
  3. Invoker 구현
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    public class Waiter {
    
     private List<Order> orders = new ArrayList<>();
    
     public void takeOrder(Order order) {
         orders.add(order);
     }
    
     public void placeOrders() {
         for (Order order : orders) {
             order.execute();
         }
         orders.clear();
     }
     }
    
  4. 테스트
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
    public class Restaurant {
    
     public static void main(String[] args) {
         Chief chief = new Chief();
         Waiter waiter = new Waiter();
    
         // Create orders
         Order order1 = new CookOrder(chief, "Steak with fries");
         Order order2 = new CookOrder(chief, "Pasta Carbonara");
    
         // Waiter takes orders
         waiter.takeOrder(order1);
         waiter.takeOrder(order2);
    
         waiter.placeOrders();
    
     }
    }
    
This post is licensed under CC BY 4.0 by the author.

© bear-su. Some rights reserved.