일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 어떻게 나답게 살 것인가
- 함수형 프로그래밍
- 소프시스 밤부 좌식 엑슬 테이블
- 아비투스
- 한달독서
- 테트리스
- 커스텀린트
- 소프시스
- 캐치마인드
- T자형인재
- 안드로이드
- 목적 중심 리더십
- 좌식테이블
- 한달브런치북만들기
- 브런치작가되기
- 자취필수템
- 면접
- 베드테이블
- 한달어스
- 리얼하다
- 한단어의힘
- 지지않는다는말
- 북한살둘레길
- 재택근무
- 프래그먼트
- 1일1커밋
- 슬기로운 온라인 게임
- 베드트레이
- 끝말잇기
- 목적중심리더십
- Today
- Total
정상에서 IT를 외치다
[디자인패턴] 커맨드패턴 본문
안녕하세요. 블랙진입니다.
책 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. 주방장 = 리시버 객체
'디자인패턴' 카테고리의 다른 글
[디자인패턴] 템플릿 메소드 패턴 (0) | 2019.06.01 |
---|---|
[디자인패턴] 어댑터패턴과 퍼사드패턴 (1) | 2019.05.19 |
[디자인패턴] 팩토리패턴 (0) | 2019.05.13 |
[디자인 패턴] 데코레이터 패턴 (0) | 2019.05.12 |
[디자인패턴] IoC, DI, DIP 용어 정리 (4) | 2019.04.30 |