•
메소드 호출을 캡슐화하여 정보은닉의 정도를 더 향상시키는 방법이다.
만능 IOT 리모컨
•
7개의 슬롯이 존재하며 각 슬롯의 on, off 버튼으로 각 슬롯에 연결된 제품들을 연결 후 조작할 수 있으며 undo 버튼을 통해 마지막으로 누른 버튼의 명령을 취소할 수도 있다.
커맨드 패턴 소개
•
객체마을 식당의 음식 주문 과정
1.
고객이 종업원에게 주문을 한다.
•
createOrder()
2.
종업원은 주문을 받아서 카운터에 전달하고 주문이 들어왔음을 주방장에게 알린다.
•
takeOrder(), orderUp()
3.
주방장이 주문대로 음식을 준비한다.
•
makeBurger(), makeShake()
•
객체마을 식당 등장인물의 역할
◦
주문서
▪
주문 내용을 캡슐화한다.
▪
이 객체의 인터페이스에는 식사 준비에 필요한 행동을 캡슐화한 orderUp() 메소드가 있다.
▪
해당 식사 주문 수행하는 객체(주방장)의 참조도 존재한다. 이런 내용은 캡슐화되어 있어서 종업원은 어떤 메뉴가 주문되었는지, 어떤 주방장이 메뉴를 준비하는지 몰라도 된다.
◦
종업원
▪
주문서를 매개변수로 받고 orderUp() 메소드를 호출하는 객체다.
▪
종업원의 takeOrder() 메소드는 여러 고객의 주문서를 매개변수를 전달할 수 있다.
◦
주방장
▪
실제로 식사를 준비하는 구현에 대한 정보는 주방장만이 가지고 있다.
▪
종업원이 orderUp() 메소드를 호출하면 주방장이 그 주문을 받아서 음식을 만들때 필요한 메소드를 전부 처리한다. 여기서 주방장과 종업원은 완전히 분리되어 있다.
•
리모컨에는?
◦
위 내용을 리모컨 API에 대입해보면 리모컨 버튼을 눌렀을 때 호출되는 코드와 실제로 일을 처리하는 코드를 분리해야 한다.
◦
리모컨 슬롯에 객체마을 식당의 주문서 객체가 들어갔다면 어떨까? 버튼이 눌렸을때 orderUp() 같은 메소드가 호출되면서 리모컨은 해당 객체가 어떤 일을 하는지 모르지만 불이 켜진다거나 필요한 작업을 처리될 수 있다.
객체마을 식당과 커맨드 패턴
•
고객, 주문서, 종업원, 주방장은 커맨드 패턴에서 각각 Client, Command, Invoker, Receiver 객체들과 매핑된다.
◦
Client는 Command 객체를 생성해야 한다. createCommandObject() 메소드를 가진다.
◦
Command는 Receiver 객체의 참조와 execute() 메소드를 가지고 있으며 이는 행동을 캡슐화하며 Receiver 객체의 특정 행동을 처리한다.
◦
Invoker 객체는 Command 객체의 참조를 가지고 있으며 execute() 메소드를 호출할 수 있다.
◦
Receiver 객체는 Command의 execute() 호출에 따라 내부적으로 구현된 동작을 수행한다.
커맨드 패턴의 정의
•
커맨드 패턴을 사용하면 요청 내역을 객체로 캡슐화해서 객체를 서로 다른 요청 내역에 따라 매개변수화할 수 있다.
•
커맨드 객체는 일련의 행동을 특정 리시버와 연결함으로써 요청을 캡슐화한 것으로 행동과 리시버를 한 객체에 넣고 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
복사