디자인 패턴 - 05. 커맨드 패턴

강준혁·2022년 10월 1일
0

디자인패턴

목록 보기
5/6

커맨드 패턴

커맨드 패턴은 특정 기능을 캡슐화 하고 그 기능을 사용하는 객체가 기능의 추상화에 의존하게 함으로서 기능의 추가나 변경에 대해 유연하게 대처 가능하도록 하는 디자인 패턴이다.

커맨드 패턴의 필요성

조명의 on/off가 가능한 리모콘을 만든다고 가정하자.


class Light {
  turnOn() { ... }
  turnOff() { ... }
}

class RemoteControl {
  private Light light = new Lignt();

  turnOn() {
    light.turnOn();
  }
  
  turnOff() {
    light.turnOff();
  }
}

이 설계에서 리모콘 기능을 확장하여 티비의 on/off 또한 가능하게 하려면 어떻게 해야 할까, 기존 코드를 수정하는 것 외에는 방법이 없다.

따라서 리모컨 클래스가 조명이나 티비 객체를 직접적으로 생성하는 것이 아닌 합성을 통해서 구현해보자.


interface Electronic {
  public void turnOn();
  public void turnOff();
}

class RemoteControl {
  priavte Electronic target;

  public RemoteControl(Electronic target) {
    this.target = target;
  }

  turnOn() {
    target.turnOn();
  }
  
  turnOff() {
    target.turnOff();
  }
}

위와 같이 하면 다양한 타겟에 대한 확장성을 가져올 수 있다.

하지만 만약 Electronic 이 아닌 다른 여러 기기에 대한 기능 추가도 필요하고, 해당 기기는 Electronic 과는 다른 인터페이스를 가지는 경우에는 어떻게 해야할까? 지금 설계대로라면 리모컨 클래스는 계속해서 추가되는 인터페이스에 대한 의존성이 추가되어야 한다.

커맨드 패턴의 적용

수행하는 클래스에서는 기능의 실행을 위한 최소한의 인터페이스에만 의존하고, 해당 기능의 구현은 캡슐화 하면 위에서 언급한 문제를 해결할 수 있다.

기능의 실행을 위한 최소한의 인터페이스인 Command 인터페이스를 선언한다.

interface Command {
  public void execute();
}

각 기능들을 위 인터페이스 기반으로 구현한다.

class LightOnCommand implements Command {
  Light light;
  
  public LightOnCommand(Light light) {
    this.light = light;
  }
  
  public void execute() {
    light.turnOn();
  }
}

리모컨 클래스는 Command 인터페이스에만 의존하도록 한다.

class RemoteControl {
  priavte Command onCommand;
  priavte Command offCommand;

  public RemoteControl(Command onCommand, Command offCommand) {
    this.onCommand = onCommand;
    this.offCommand = offCommand;
  }

  turnOn() {
    onCommand.execute();
  }
  
  turnOff() {
    offCommand.execute();
  }
}
profile
백엔드 개발자

0개의 댓글