Design pattern study 6 command pattern

31
DESIGN PATTERN STUDY 6. COMMA ND PA TTERN 호호 호호호

Transcript of Design pattern study 6 command pattern

Page 1: Design pattern study 6 command pattern

DESIG

N PATT

ERN STU

DY 6.

COMMAND PATT

ERN

호출 캡슐화

Page 2: Design pattern study 6 command pattern

INDEX

1. COMMAND 패턴 소개2. COMMAND 패턴 정의3. UNDO COMMAND

Page 3: Design pattern study 6 command pattern

• 본 PPT 는 Design Patterns Study 를 위해 작성되었습니다 .

• Study 에 사용한 교재는 한빛미디어에서 나온• [Head First Desgin Patterns] 을 사용하였습니다 .

• Written by 서울시립대 이희태 For study withNHN NEXT2 기 조현호서울시립대 이희태

Page 4: Design pattern study 6 command pattern

1. COMMAND 패

턴 소개

Page 5: Design pattern study 6 command pattern

안녕하십니까 ?

저희가 새로 개발한 홈 오토메이션 리모컨의 API 디자인을 의뢰하고자 합니다 .

저희 회사에서 개발 중인 최신형 리모컨 시제품을 동봉해 드리겠습니다 . 이 리모컨에는 일곱 가지 프로그래밍이 가능한 슬롯과 각 슬롯에 대한 ON/OFF

스위치가 있습니다 . 각 슬롯은 다양한 가정용 기기에 연결할 수 있습니다 .

리모컨에는 작업취소 버튼도 장착되어 있습니다 .

그리고 조명 , 팬 , 욕조 , 오디오를 비롯한 장비들을 제어하기 위한 용도로 다양한 업체에서 공급받은 자바 클래스들을 CD 에 동봉해서 보내드립니다 . 각 슬롯을 한 가지 기기 또는 하나로 엮어 있는 일련의 기기들에 할당할 수 있도록 리모컨을 프로그래밍하기 위한 API 를 제작해주시길 부탁 드립니다 .

여러분께서 설계하신 디자인을 하루 빨리 볼 수 있기를 기대하고 있겠습니다 .

건승을 기원합니다 .

빌 “ X – 10” 톰슨 , CEO

디자인 의뢰가 들어왔네요 .

Page 6: Design pattern study 6 command pattern

동봉된 리모컨을 살펴봅시다 .

1 번 슬롯에 연결되는 가전제품 제어

2 번 슬롯에 연결되는 가전제품 제어

. . .

버튼들이 쭉 나열된다 .

7 가지 프로그래밍이 가능한 슬롯 . 각 슬롯에 원하는 제품을 연결한 후 우측의 버튼으로 조작할 있다 .

Undo 버튼 : 마지막으로 누른 버튼에 대한 명령 취소

제어할 수 있는 제품의 이름이 등록

Page 7: Design pattern study 6 command pattern

CD 에 동봉된 클래스들을 살펴보자 .

on()off()dim()

CeilingLight

on()off()

OutdoorLight

on()off()setInputChannel()setVolume()

TV

on()off()setCD()setDvd()setRadio()setVolume()

Stereoup()down()lightOn()lightOff()

GarageDoor

high()medium()low()off()getSpeed()

CeilingFan

setDuskTime()setDawnTime()manualOn()manualOff()

GardenLight

on()off()

Light

jetsOn()jetsOff()Circulate()setTemperature()

Hottub

waterOn()waterOff()

Sprinkler

openValue()closeValue()

FaucetControl

Page 8: Design pattern study 6 command pattern

리모컨 API 디자인 설계

지금 바로 위의 가전제품 클래스들을 리모컨에 부착하도록 설계하면 어떨까 ?

문제점1. 바뀌는 부분을 따로 캡슐화하지 않았다 .

2. 상위 클래스가 아닌 구체적인 클래스들에 의존하고 있다 .

3. 리모컨에 부착하는 구체적인 가전제품 클래스들이 새로 추가 , 변경될 때마다 리모컨의 코드를 고쳐야 한다 .

4. 가전제품에 따라 리모컨 on/off 버튼에 해당되는 메소드 호출이 다 달라야만 한다 .

5. 리모컨에서 가전제품 클래스에 대해 정보은닉이 되고 있지 않는다 .

Page 9: Design pattern study 6 command pattern

즉 ,리모컨의 버튼과 가전제품의 특정 기능 (ex. On, off) 들이 전혀 분리되어 있지 않다 . Client 에서 특정 작업 요청이 이루어질 때 그 요청 호출을 캡슐화할 필요가 있다 .

Command Pat-tern 을 사용한다 !

Page 10: Design pattern study 6 command pattern

레스토랑에 잠깐 들려보자…

JAVA Restaurant

Page 11: Design pattern study 6 command pattern

연어스테이크 ,카바 (cava)

createOrder() takeOrder()

OrderUp()

주문서(Order 객체 )

makeSteak()makeWine()

Page 12: Design pattern study 6 command pattern

연어스테이크 ,카바 (cava)

웨이트리스와 요리사가 구분되어있다 .

이 둘은 Order 객체 – 주문서 – 를 통해서 소통할 뿐이다 .

요리사는 요리에 필요한 정보만 가지고 있다 . 요리를 하지 주문을 받지는 않는다 .

웨이트리스는 주문서를 식사를 준비시킨다 .요리를 하지 않는다 .

Page 13: Design pattern study 6 command pattern

2.COMMAND PA

TTERN

정의

Page 14: Design pattern study 6 command pattern

exe-cute

()

exe-cute

()

Client Command

Command

Invoker

Receiver

createCommandOb-ject()

Invoker.setCommand(Command sth)

set-Com-mand()

execute()

action1()action2()

action1()action2() 의 결과물

Page 15: Design pattern study 6 command pattern

JAVA Restaurant Command Pattern

손님 Client 객체

주문서 Command 객체takeOrder() setCommand()

웨이트리스 Invoker 객체orderUp() execute()

주방장 Receiver 객체

레스토랑과 커맨드패턴의 비교

Page 16: Design pattern study 6 command pattern

COMMAND PATTERN 이란 ?

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

Page 17: Design pattern study 6 command pattern

UML 다이어그램

+setCom-mand()

커맨드 객체에게 Exe-cute() 를 실행하도록 요청 <Interface>

매개변수로 command 객체를 받음

ConcreteCommand 를 생성한 후 그 객체에 특정 Receiver 를 넣어줌

구현된 Excetute() 메소드에서는 re-ceiver 의 메소드 (Action()) 를 호출하여 요청된 작업을 수행 ( 호출의 캡슐화 )

Page 18: Design pattern study 6 command pattern

command Interface

Page 19: Design pattern study 6 command pattern

Receiver

Page 20: Design pattern study 6 command pattern

Invoker

Page 21: Design pattern study 6 command pattern

NoCom-mandNoCommand 가 없다면 ?

☞ NoCommand 는 on/offButtonWasPushed() 메소드를 더 간단하게 만든다 .

Page 22: Design pattern study 6 command pattern

setCommand()

public void setCommand(int slot, Command onCommand, Com-mand offCommand)

- Invoker( = RemoteControl) 의 각 slot 에 concreteCommand 객체를 등록하는 메소드

Page 23: Design pattern study 6 command pattern

RemoteControlTest(1)

Page 24: Design pattern study 6 command pattern

RemoteControlTest(2)

Page 25: Design pattern study 6 command pattern

3. UNDO C

OMMAND

Page 26: Design pattern study 6 command pattern

작업취소 (UNDO) 버튼 ?

바로 이전 상태로 되돌린다 !

Page 27: Design pattern study 6 command pattern

Interface 에 undo() 메소드를 선언해준다 .

concreteCommand 객체에서 undo() 메소드를 구현한다 . On Command 객체라면 -> off 로 , Off Command 객체라면 On 으로 작업취소 명령을 정의해준다 .

Undo() 가 추가된 Command 객체

Page 28: Design pattern study 6 command pattern

Invoker

undoCommand 객체를 멤버변수로 넣어주고…

여기에도 noCommand 대입

사용자가 버튼을 누르면 우선 해당 Command를 실행한 뒤 (=execute() 호출한 후 ), 바로 그 객체의 레퍼런스를 undoCommand 변수에 할당해준다 .

사용자가 undoButton 을 누르면 현재 저장된 undo-Command 객체의 undo() 메소드를 호출한다 .그러면 마지막으로 했던 작업이 취소된다 .

Page 29: Design pattern study 6 command pattern

RemoteControlTest, Console 출력

livingRoomLightOn.exe-cute()livingRoomLightOff.exe-cute()livingRoomLightOff.undo()

livingRoomLightOff 에서의 작업취소

Page 30: Design pattern study 6 command pattern

Q/A

Q1. 항상 리시버가 필요한가요 ? 커맨드 객체에서 execute() 를 구현해 버리면 안되나요 ?

ans) 일반적으로 리시버에 있는 행동을 호출하는 “더미” 커맨드 객체를 만든다 . 하지만 요구사항의 전부는 아니더라도 대부분을 요구하는 “스마트” 커맨드 객체를 만드는 경우도 자주 볼 수 있다 . 물론 커맨드객체에서 대부분의 행동을 처리해도 된다 . 하지만 그렇게 하면 여기에서 우리가 했던 수준으로 인보커와 리시버를 분리시키는 것이 불가능해지고 , 리시버를 이용해서 커맨드를 매개변수화하는것도 할 수 없다 .

Q2. 작업 취소를 할 때 히스토리 기능은 어떻게 구현할 수 있나요 ? 즉 , UNDO버튼을 여러 번 누를 수 있도록 하려면 어떻게 해야 하나요 ?

ans) 간단하다 . 앞에서는 undoCommand 에 마지막으로 실행한 커맨드에 대한 레퍼런스를 그냥 대입했는데 , 여기서는 스택을 이용하여 이전에 실행한 커맨드를 순서대로 저장하면 된다 . 그리고 나서 사용자가 undo 버튼을 누를 때마다 스택의 맨 위에서부터 항목을 꺼내서 undo() 메소드를 호출하기만 하면 된다 .

Page 31: Design pattern study 6 command pattern

Than

k yo

u!