정상에서 IT를 외치다

[디자인패턴] 커맨드패턴 본문

디자인패턴

[디자인패턴] 커맨드패턴

Black-Jin 2019. 5. 18. 22:40
반응형

안녕하세요. 블랙진입니다.

책 HeadFirstDesignPattern 을 보며 코드를 Kotlin 으로 바꿔가며 공부한 내용입니다.


호출 캡슐화


- 메소드 호출을 캡슐화하는 방법에 대해 배워보겠습니다.



커맨드 패턴


커맨드 패턴을 이용하면 요구 사항을 객체로 캡슐화 할 수 있으며, 매개변수를 써서 여러 가지 다른 요구 사항을 집어넣을 수도 있습니다. 또한 요청 내역을 큐에 저장하거나 로그로 기록할 수도 있으며, 작업 취소 기능도 지원가능합니다


커맨드 패턴을 이용하면 요청을 하는 객체와 그 요청을 수행하는 객체를 분리시킬 수 있습니다.



사용방법


커맨드 객체는 일련의 행동을 특정 리시버하고 연결시킴으로써 요구 사항을 캡슐화합니다. 이렇게 하기 위해서 행동과 리시버를 한 객체에 집어넣고, excute()라는 메소드 하나만 외부에 공개하는 방법을 씁니다. 이 메소드 호출에 의해서 리시버에서 일련의 작업이 처리됩니다. 외부에서 볼 때는 어떤 객체가 리시버 역활을 하는지, 그 리시버에서 실재로 어떤 일을 하는지 알 수 없습니다.


문제 해결을 하기 전에 객체마을 식당 예제를 살펴보겠습니다. 객체 마을에서는 다음과 같은 과정으로 주문이 이뤄집니다.


고객 -> createOrder -> 주문서 -> takeOrder() -> 웨이트리스 -> orderUp() -> 주문서 -> makeBurger(), makeShake() -> 주방장


커맨드 패턴 다이어그램과 비교해 봅시다.


클라이언트 -> createCommandObject() -> 커맨드 -> setCommand() -> 인보커 -> execute() -> 커맨드 -> action1(), action2() -> 리시버


이를 코드로 비교 분석해 보겠습니다.


class Client {

fun createOrder() = Order()
}

1. 고객은 createOrder 통해 주문서를 생성합니다.

= 클라이언트의 createCommandObject() 를 통해 커맨드 객체를 생성합니다.


interface Command {

fun execute()
}

class Order {

var waitress: Command? = null


fun takeOrder(command: Command) {
this.waitress = command

}

fun orderUp() {
waitress?.execute()

}
}

2. 주문서는  takeOrder 통해 웨이트리스에게 주문을 전달합니다.

= 커맨드 객체는 setCommand 통해 인보커에게 커맨드 객체를 넘겨줍니다.


3. 웨이트리스는 orderUp 통해 주문서가 주방장에게 지시를 내리도록 합니다.

= 인보커는 execute 통해 커맨드 객체가 리시버에게 지시를 내립니다.


class Chef {

fun makeBurger() {
println("햄버거를 만듬")
}

fun makeShaker() {
println("쉐이커를 만듬")
}
}


class ChefCommand(val chef: Chef): Command {
override fun execute() {
chef.makeBurger()
chef.makeShaker()
}
}

4. 주문서는 주방장에게 makeBurger(), makeShake() 호출을 지시합니다.

= 커맨드 객체는 리시버에게 action1(). action2() 호출을 지시합니다.




사용 정리

/**
* 1. 클라이언트에서 커맨드 객체 생성
* 2. setCommand()를 호출하여 인보커에 커맨드 객체를 저장
* 3. 나중에 클라이언트에서 인보커한테 그 명령을 실행 시켜 달라는 요청을 함
* 4. 인보커는 명령을 실행합니다.
*/
fun main() {

val client = Client()

//1. 고객은 createOrder 통해 주문서를 생성합니다.
val order = client.createOrder()

//4. 주문서는 주방장에게 makeBurger(), makeShake() 호출을 지시합니다.
val chef = Chef()
val cookCommand = ChefCommand(chef)

//2. 주문서는 takeOrder 통해 웨이트리스에게 주문을 전달합니다.
order.takeOrder(cookCommand)

//3. 웨이트리스는 orderUp 통해 주문서가 주방장에게 지시를 내리도록 합니다.
order.orderUp()

}


1. 고객 = 클라이언트객체 / 주문서 = 커맨드 객체

2. takeOrder() = setCommand()

3. 웨이트리스 = 인보커 객체 / orderUp() = execute()

4. 주방장 = 리시버 객체

반응형
Comments