[디자인 패턴] 커맨드 패턴 :: 잡다한 프로그래밍
반응형

1. 커맨드 패턴의 정의

커맨드 패턴은 객체의 행위(메서드)를 클래스로 만들어 캡슐화 하는 패턴입니다.

 

즉, 어떤 객체(A)에서 다른 객체(B)의 메서드를 실행하려면 그 객체(B)를 참조하고 있어야 하는 의존성이 발생합니다.

그러나 커맨드 패턴을 적용하면 의존성을 제거할 수 있습니다.

 

즉 내가 B라는 객체의 메서드를 실행 시킬때 B를 실행시키는걸 모른채로 메서드를 실행하게 만든다.


2. 예시

다음과 같이 Lamp를 on 하는 클래스가 주어지고, 이를 사용할 Remote 클래스를 다음과 같이 만든다.

 

Lamp 클래스

public class Lamp {
    public void On(){
        System.out.println("Lamp on");
    }
}

 

Remote 클래스

public class Remote {
    private Lamp lamp;

    public Remote(Lamp lamp){
        this.lamp = lamp;
    }

    public void execute(){
        lamp.on();
    }
}

 

Client 클래스

 

public class Client {
    public static void main(String args[]){
        Lamp lamp = new Lamp();
        Remote remote = new Remote(lamp);
        remote.execute();
    }
}

만약 다음과 같이 Remote코드를 작성했을 경우 Lamp ON 이외에 다른 클래스(Streo On)가 주어질 경우 Remote가 수정되어야 하는 문제가 생긴다. 따라서 커맨드 패턴을 적용하면 다음과 같다.

 

Command 클래스

public interface Command {
          public void execute();
 }

 

LightOnCommand 클래스

public class LightOnCommand implements Command {

          Light light;   //이 Light 객체는 실제 불키는 방법을 알고있는 리시버 객체

          public LightOnCommand(Light light) {
                   this.light = light;
          }

          public void execute() {
                   light.on();
          }
 }

 

SimpleRemoteControl 클래스 (인보커)

public class SimpleRemoteControl {
          Command slot;

          public SimpleRemotecontrol() { }
         
          public void setCommand(Command command) {
                   slot = command;
          }

          public void buttonWasPressed() {
                   slot.execute();
          }
 }

 

RemoteControlTest 클래스 (클라이언트)

public class RemoteControlTest {
          public static void main(String[] args) {
          
                   SimpleRemoteControl remote = new SimpleRemoteControl();
                   Light light = new Light();
                   LightOnCommand lightOn = new LightOnCommand(light);

                   remote.setCommand(lightOn);
                   remote.buttonWasPressed();
          }           
 }

 

즉 커맨드 패턴은 다음과 같은 구조를 띄게 된다. 따라서 Lamp 이외의 클래스를 사용하려면 LightOnCommand와 같은 XXXCommand 클래스를 만들고 적용할 수 있기 때문에 확장에 용이하다.


3. 커맨드 패턴의 적용 예시

java의 Thread가 커맨드 패턴이 적용된 예시이다.

메인 클래스의 Thread 객체에서 start를 통해 Command의 run 메소드를 실행시키지만 Thread 입장에서는 어떤것을 실행시키는지 알 수 없다.

따라서 run = execute를 의미, start = buttonWasPressed를 의미한다.

public class Main {
  public static void main(String[] args) {
    Thread t = new Thread(new Command());
    t.start();  /* run을 실행하지만 Command가 무엇을 하는지는 모른다 */
  }
}

class Command implements Runnable {
  @Override
  public void run() {
    System.out.println("RUN!");
  }
}
반응형

+ Recent posts