////
Search
Duplicate
🌕

Chapter 06. Command

메소드 호출을 캡슐화하여 정보은닉의 정도를 더 향상시키는 방법이다.

만능 IOT 리모컨

7개의 슬롯이 존재하며 각 슬롯의 on, off 버튼으로 각 슬롯에 연결된 제품들을 연결 후 조작할 수 있으며 undo 버튼을 통해 마지막으로 누른 버튼의 명령을 취소할 수도 있다.

커맨드 패턴 소개

객체마을 식당의 음식 주문 과정
1.
고객종업원에게 주문을 한다.
createOrder()
2.
종업원은 주문을 받아서 카운터에 전달하고 주문이 들어왔음을 주방장에게 알린다.
takeOrder(), orderUp()
3.
주방장이 주문대로 음식을 준비한다.
makeBurger(), makeShake()
객체마을 식당 등장인물의 역할
주문서
주문 내용을 캡슐화한다.
이 객체의 인터페이스에는 식사 준비에 필요한 행동을 캡슐화한 orderUp() 메소드가 있다.
해당 식사 주문 수행하는 객체(주방장)의 참조도 존재한다. 이런 내용은 캡슐화되어 있어서 종업원은 어떤 메뉴가 주문되었는지, 어떤 주방장이 메뉴를 준비하는지 몰라도 된다.
종업원
주문서를 매개변수로 받고 orderUp() 메소드를 호출하는 객체다.
종업원takeOrder() 메소드는 여러 고객의 주문서를 매개변수를 전달할 수 있다.
주방장
실제로 식사를 준비하는 구현에 대한 정보는 주방장만이 가지고 있다.
종업원이 orderUp() 메소드를 호출하면 주방장이 그 주문을 받아서 음식을 만들때 필요한 메소드를 전부 처리한다. 여기서 주방장과 종업원은 완전히 분리되어 있다.
리모컨에는?
위 내용을 리모컨 API에 대입해보면 리모컨 버튼을 눌렀을 때 호출되는 코드와 실제로 일을 처리하는 코드를 분리해야 한다.
리모컨 슬롯에 객체마을 식당의 주문서 객체가 들어갔다면 어떨까? 버튼이 눌렸을때 orderUp() 같은 메소드가 호출되면서 리모컨은 해당 객체가 어떤 일을 하는지 모르지만 불이 켜진다거나 필요한 작업을 처리될 수 있다.

객체마을 식당과 커맨드 패턴

고객, 주문서, 종업원, 주방장은 커맨드 패턴에서 각각 Client, Command, Invoker, Receiver 객체들과 매핑된다.
ClientCommand 객체를 생성해야 한다. createCommandObject() 메소드를 가진다.
CommandReceiver 객체의 참조와 execute() 메소드를 가지고 있으며 이는 행동을 캡슐화하며 Receiver 객체의 특정 행동을 처리한다.
Invoker 객체는 Command 객체의 참조를 가지고 있으며 execute() 메소드를 호출할 수 있다.
Receiver 객체는 Commandexecute() 호출에 따라 내부적으로 구현된 동작을 수행한다.

커맨드 패턴의 정의

커맨드 패턴을 사용하면 요청 내역을 객체로 캡슐화해서 객체를 서로 다른 요청 내역에 따라 매개변수화할 수 있다.
커맨드 객체는 일련의 행동을 특정 리시버와 연결함으로써 요청을 캡슐화한 것으로 행동과 리시버를 한 객체에 넣고 execute()라는 메소드 하나만 외부에 공개하는 식으로 사용해야 한다.
이 메소드 호출에 따라 리시버가 일련의 작업을 처리한다.
밖에서 볼 때는 어떤 객체가 리시버 역할을 하는지, 그 리시버가 무슨 일을 어떻게 하는지 알 수 없다. 그냥 execute() 메소드를 호출하면 해당 요청이 처리된다는 것만 알 수 있다.
명령으로 객체를 매개변수화하는 몇 가지 사례도 볼 수 있다. 앞선 예제에서는 조명 켜기 명령을 로딩하여 실행했다가 차고 문열기 명령을 로딩하셔 실행하기도 했다.
종업원이나 리모컨은 특정 인터페이스만 구현되어 있다면 해당 커맨드 객체가 무슨 일을 하는지 전혀 신경쓸 필요가 없다.
public class RemoteControlTest { public static void main(String[] args) { SimpleRemoteControl remote = new SimpleRemoteControl(); Light light = new Light(); GarageDoor garageDoor = new GarageDoor(); LightOnCommand lightOn = new LightOnCommand(light); GarageDoorOpenCommand garageOpen = new GarageDoorOpenCommand(garageDoor); remote.setCommand(lightOn); remote.buttonWasPressed(); remote.setCommand(garageOpen); remote.buttonWasPressed(); } }
Java
복사

커맨드 패턴 클래스 다이어그램 살펴보기