1) 필요성
(1) 식당에서 '햄버거1'이라는 메뉴를 시키는데 필요한 함수가
몇가지 있다고 하자 해당 제품 주문시
'참깨 빵 위에 순 쇠고기 패티 두 장, 특별한 소스, 양상추, 치즈, 피클, 양파'
라는 과정이 진행된다.
근데 실제로 주문시 보통 그렇게 하지 않고 '버거1플리즈' 라고 하면
알아서 나오는데...
웨이터가 손님에게 메뉴를 통해서 주문을 받고
, 제품을 주고 2가지 메서드를 통해서
주문과 제품을 처리하고
요리사는 주문 받을때 얻은 메뉴명에 따라 필요한 작업을
진행하도록 풀면 그게 커맨트 패턴임.
2) 방향
(1) 객체 정의
메뉴- 커맨드 객체,
웨이터- 인보커 객체,
손님- 클라이언트 객체,
주방장- 리시버 객체,
주문받기- setCommand()
제품주기- execute(),
2. 구현
1) Command 인터페이스 작성
package commander; public interface ICommand { public void execute(); public void undo(); }
2) 리시버 작성
package Product; public class Hamberger { public void make() { System.out.println("make hamberger"); } public void makeBack(){ System.out.println("Back order"); } }
3) Command 작성
ps. 여기서는 햄버거 만드는방법 연결을 하나로 처리함
근데 여러 기능이 있는 경우 ICommand를 상속받아
따로 만드는것도 가능(ex) 햄버거 곱배기 커맨더)
다른 예제에 따르면 전등 on, 전등off를
2개의 클래스에서 각각의 execute() 로 구현
package command; import commander.ICommand; import Product.Hamberger; public class HambergerCommand implements ICommand { Hamberger hamberger; public HambergerCommand(Hamberger hamberger){ this.hamberger=hamberger; } @Override public void execute() { hamberger.make(); } @Override public void undo() { hamberger.makeBack(); } }
4) 이걸 사용할 인보커 작성 (main)
package runProject; import commander.ICommand; public class SimpleRemoteControl { ICommand slot; public SimpleRemoteControl(){ } public void setCommand(ICommand command){ slot=command; } public void buttonWasPressed(){ slot.execute(); } public void buttonBack(){ slot.undo(); } }
5) test 소스
package runProject; import command.HambergerCommand; import Product.Hamberger; public class RunProject { public static void main(String[] args) { SimpleRemoteControl remote = new SimpleRemoteControl(); Hamberger hamberger = new Hamberger(); HambergerCommand hamCommand = new HambergerCommand(hamberger); remote.setCommand(hamCommand); remote.buttonWasPressed(); remote.buttonBack(); } }
결과 :
make hamberger
Back order
6) 5)까지 진행한 상태에서 우리가 원하는 햄버거를 얻도록
아래와 같이 클래스 들을 변경한다.
(1) 2) 리시버에서 작성한 햄버거 작성방법에 지저분하지만
좀 주문에 맞는 내용일 넣어본다.
이제 좀 햄버거 만드는 일이 되었음.
package Product; public class Hamberger { public void grillBun(){ System.out.println("햄버거 빵을 굽다"); } public void putBun(){ System.out.println("참깨빵을 놓다."); } public void grillPatty(){ System.out.println("햄버거 패티를 굽다"); } public void putPatty(){ System.out.println("햄버거 패티를 놓다"); } public void putSource(){ System.out.println("특별한(자바소스)를 놓는다."); } public void putlettuce(){ System.out.println("양상추를 놓는다."); } public void putcheese(){ System.out.println("치즈를 놓는다."); } public void putOnion(){ System.out.println("양파를 놓는다."); } public void make() { System.out.println("make hamberger"); } public void makeBack(){ System.out.println("Back order"); } }
(2) 3) 에서 작성한 커맨드 클래스를 아래와 같이 변경한다.
execute() 함수만 좀 달라진걸 확인할 수 있음.
(3) 다 작성되었고 실행~ 여기서도 충분히
정리가 가능하겠지만 이정도에서 마무리.
치즈추가, 양파추가 이것도 가능하려면
각각의 옵션을 클래스로 추가해서 구현해주고
주문(test 클래스) 시 객체를 몇개 더 추가해서 진행하면
될듯.
ps. 실제 사용시 execute 이외의 undo 같은 여러 메서드들이
추가되어 사용될 것이다.
ps. 실제 사용시 execute 이외의 undo 같은 여러 메서드들이
추가되어 사용될 것이다.
package command; import commander.ICommand; import Product.Hamberger; public class Hamberger1Command implements ICommand { Hamberger hamberger; public Hamberger1Command(Hamberger hamberger){ this.hamberger=hamberger; } @Override public void execute() { hamberger.grillBun(); hamberger.putBun(); hamberger.grillPatty(); hamberger.putPatty(); hamberger.grillPatty(); hamberger.putPatty(); hamberger.putSource(); hamberger.putlettuce(); hamberger.putcheese(); hamberger.putOnion(); } @Override public void undo() { hamberger.makeBack(); } }
결과 :
햄버거 빵을 굽다
참깨빵을 놓다.
햄버거 패티를 굽다
햄버거 패티를 놓다
햄버거 패티를 굽다
햄버거 패티를 놓다
특별한(자바소스)를 놓는다.
양상추를 놓는다.
치즈를 놓는다.
양파를 놓는다.
3. 다이어그램
패턴에 대한 다이어그램은 아래 위키백과를 참고바랍니다.
댓글 없음:
댓글 쓰기