差分

このページの2つのバージョン間の差分を表示します。

この比較画面へのリンク

両方とも前のリビジョン前のリビジョン
次のリビジョン
前のリビジョン
study:java:design_pattern:command [2008/09/02 15:34] bananastudy:java:design_pattern:command [2012/12/11 14:02] (現在) – [the Definition of Command Pattern] banana
行 9: 行 9:
 하나씩 살펴볼까요? 커맨드 객체는 일련의 행동을 특정 리시버하고 연결시킴으로써 요구사항을 캡슐화한 것입니다. 하나씩 살펴볼까요? 커맨드 객체는 일련의 행동을 특정 리시버하고 연결시킴으로써 요구사항을 캡슐화한 것입니다.
 이렇게 하기 위해서 행동과 리시버를 한 객체에 집어넣고, execute()라는 메소드 하나만, 외부에 공개하는 방법 이렇게 하기 위해서 행동과 리시버를 한 객체에 집어넣고, execute()라는 메소드 하나만, 외부에 공개하는 방법
-을 씁니다. 이 메소드 호출에 의해서 리시버에서 일련의 작업이 처리됩니다. 외부에서 볼 때는 어떤 객체가 리시 +을 씁니다. 이 메소드 호출에 의해서 리시버에서 일련의 작업이 처리됩니다. 외부에서 볼 때는 어떤 객체가 리시버 
-버 역할을 하는지, 그 리시버에서 실제로 어떤 일을 하는지 알 수 없습니다. 그냥 execute() 메소드를 호출하면+ 역할을 하는지, 그 리시버에서 실제로 어떤 일을 하는지 알 수 없습니다. 그냥 execute() 메소드를 호출하면
 요구 사항이 처리된다는 것만 알 수 있을 뿐이죠. 요구 사항이 처리된다는 것만 알 수 있을 뿐이죠.
  
 이제 커맨드 패턴의 클래스 다이어그램을 살펴보도록 하겠습니다. 이제 커맨드 패턴의 클래스 다이어그램을 살펴보도록 하겠습니다.
 +
 +{{keywords>Command Pattern}}
  
 ===== Class Diagram ===== ===== Class Diagram =====
行 20: 行 22:
 Command Pattern의 예로서 가전제품을 조정 가능한 리모컨 API을 살표보도록 하겠습니다. Command Pattern의 예로서 가전제품을 조정 가능한 리모컨 API을 살표보도록 하겠습니다.
 이왕이면 작업취소 기능까지 구현해보겠습니다. 이왕이면 작업취소 기능까지 구현해보겠습니다.
 +
 +
  
 ===== Command class implements an undo function ===== ===== Command class implements an undo function =====
行 53: 行 57:
      light.off();      light.off();
   }   }
 +}
 +</code>
 +
 +정말 식은 죽 먹기군요. 이제 %%LightOffCommand%%를 살펴볼까요? 이 클래스의 undo()메소드에서는 Light의
 +on()메소드만 호출하면 되겠군요.
 +
 +<code java>
 +public class LightOffCommand implements Command{
 +  Light light;
 +
 +  public LightOffCommand(Light light){
 +     this.light = light;
 +  }
 +
 +  public void execute(){
 +     light.off();
 +  }
 +
 +  public void undo(){
 +     light.on();
 +  }
 +}
 +</code>
 +
 +정말 쉽죠? 아직 끝난 건 아닙니다. %%RemoteControl%% 클래스에 사용자가 마지막으로 누른 버튼을 기록하고, undo버튼이
 +눌렸을 때 필요한 작업을 처리하기 위한 코드를 추가해야 합니다.
 +
 +
 +
 +===== Invoker Class =====
 +<code java>
 +public class RemoteControlWithUndo{
 +    Command[] onCommands;
 +    Command[] offCommands;
 +    Command undoCommand;
 +
 +    public RemoteControlWithUndo(){
 +       onCommands = new Command[7];
 +       offCommands = new Command[7];
 +
 +       Command noCommand = new NoCommand();
 +       for(int i=0; i<7; i++){
 +          onCommands[i] = noCommand;
 +          offCommands[i]= noCommand;
 +       }
 +       undoCommand = noCommand;
 +    }
 +
 +    public void setCommand(int slot, Command onCommand, Command offCommand)[
 +       onCommands[slot] = onCommand;
 +       offCommands[slot] = offCommand;
 +    }
 +
 +    public void onButtonWasPushed(int slot){
 +       onCommands[slot].execute();
 +       undoCommand = onCommands[slot];
 +    }
 +
 +    public void offButtonWasPushed(int slot){
 +       offCommands[slot].execute();
 +       undoCommand = offCommands[slot];
 +    }
 +
 +    public void undoButtonWasPushed(){
 +       undoCommand.undo();
 +    }
 +    
 +    public String toString(){
 +       //toString 코드
 +    }
 +}
 +</code>
 +
 +여기서 %%NoCommand%%는 아무것도 하지 않는 Null 객체((딱히 리턴할 객체는 없지만 클라이언트 쪽에서 null을 처리하지 않아도 되도록 하고 싶을 때 널 객체를 활용하면 좋습니다. 예를 들어, 리모컨의 경우에, 처음 리모컨을 가지고 왔을 때는 아무 명령도 할당되지 않은 상태이므로, exeucte() 메소드가 호출됐을 때 아무 일도 하지 않지만, 빈 자리를 채우기 위한 용도로 %%NoCommand%%라는 객체를 집어넣어 두면 편하겠죠. 널 객체는 여러 디자인 패턴에서 유용하게 쓰입니다. 널 객체를 일종의 디자인 패턴으로 분류하기도 합니다.))입니다. 
 +
 +===== Client Class =====
 +undo 버튼을 테스트 할 수 있는 테스트용 클래스를 만들어 보겠습니다.
 +
 +<code java>
 +public class RemoteLoader{
 +   public static void main(String[] args){
 +      RemoteControlWithUndo remoteControl = new RemoteControlWithUndo();
 +
 +      Light livingRoomLight = new Light("Living Room");
 +
 +      LightOnCommand livingRoomLightOn = new LightOnCommand(livingRoomLight);
 +      LightOffCommand livingRoomLightOff = new LightOffCommand(livingRoomLight);
 +
 +      remoteControl.setCommand(0, livingRoomLightOn, livingRoomLightOff);
 +      
 +      remoteControl.onButtonWasPushed(0);
 +      remoteControl.offButtonWasPushed(0);
 +      System.out.println(remoteControl);
 +      remoteControl.undoButtonWasPushed(0);
 +      remoteControl.offButtonWasPushed(0);
 +      remoteControl.onButtonWasPushed(0);
 +      System.out.println(remoteControl);
 +      remoteControl.undoButtonWasPushed(0);
 +
 +   }
 +
 } }
 </code> </code>

QR Code
QR Code study:java:design_pattern:command (generated for current page)