커맨드 패턴과 실사용 예제
명령(Command) 패턴
요청받은 일을 누가, 어떻게 처리하는지 알 수 없을 때 요청 자체를 캡슐화함으로써 서로 다른 요청 내역에 따라 매개변수화할 수 있다.
USE-CASE
음식을 주문받고 이를 요리하는 요리사가 있다고 하자. 요리사는 주문을 받아 요리를 하지만, 웨이터는 요리사가 누구인지, 어떻게 요리를 하는지 알 수 없다. 단지 웨이터는 주문서를 카운터에 전달한다. 이처럼 요청받은 연산이 무엇이며, 이를 처리할 객체가 누구인지에 대한 정보 없이 임의의 객체에 메세지를 보내야 할 때가 간간이 있다. 이때 명령 패턴을 사용하면 된다.
명령 패턴의 구성
- Command(주문) : 연산 수행에 필요한 인터페이스
- ConcreteCommand() : 실제 연산을 수행하는 클래스
- Client : ConcreteCommand 객체를 생성
- Invoker : ConcreateCommand의 연산을 수행하도록 요청
- Receiver : 요청에 관련된 연산 수행을 담당
구현
- 커맨드 인터페이스 구현
1 2 3
public interface Order { void execute(); }
- 커맨드 클래스 구현
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); } }
- 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(); } }
- 테스트
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.