Command Pattern 이란?

  • 요청을 객체의 형태로 캡슐화하여 재이용하거나 취소할 수 있도록 요청에 필요한 정보를 저장하거나 로그에 남기는 패턴
  • 요청에 사용되는 각 명령어들을 추상 클래스와 구체 클래스로 분리하여 단순화
  • 요청을 객체화시키기에 상태가 남게 되며 이는 나중에 작업을 취소하거나 로그 등에 활용할 수 있다.

  • Invoker : Client가 요청을 전달하는 매개체, 내부에서 적절한 Command에게 해당 요청을 처리하도록 위임
  • Receiver : 요청을 처리하기 위해 수행해야 하는 일을 가지는 객체
  • Command
    요청을 실행, 취소하는 기능을 가지는 인터페이스
    Receiver에게 요청을 처리해달라고 Invoker의 명령을 전달
  • ConcreteCommand
    Receiver가 처리해야 하는 일을 실제로 구현
    Invoker에서 execute(), undo()등 호출을 통해 요청이 오면 Receiver에게 전달

커맨드 패턴 적용

Command - 요청을 실행, 취소하는 기능을 가지는 인터페이스, Receiver에게 요청을 처리해달라고 Invoker의 명령을 전달

package BehavioralPattern.Command;

public interface Command {
    public void execute();
}

Receiver - 요청을 처리하기 위해 수행해야 하는 일을 가지는 객체

package BehavioralPattern.Command;

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

    public void off() {
        System.out.println("Light off");
    }
}

public class AirConditioner {
    public void on() {
        System.out.println("Light on");
    }

    public void off() {
        System.out.println("Light off");
    }
}

ConcreteCommand - Receiver가 처리해야 하는 일을 실제로 구현

package BehavioralPattern.Command;

public class LightOnCommand implements Command{
    private Light light;

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

    @Override
    public void execute() {
        light.on();
    }
}
public class LightOffCommand implements Command{
    private Light light;

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

    @Override
    public void execute() {
        light.off();
    }
}
package BehavioralPattern.Command;

public class AirConditionerOnCommand implements Command{
    private AirConditioner airConditioner;

    public AirConditionerOnCommand(AirConditioner airConditioner) {
        this.airConditioner = airConditioner;
    }

    @Override
    public void execute() {
        airConditioner.on();
    }
}
public class AirConditionerOffCommand implements Command{
    private AirConditioner airConditioner;

    public AirConditionerOffCommand(AirConditioner airConditioner) {
        this.airConditioner = airConditioner;
    }

    @Override
    public void execute() {
        airConditioner.off();
    }
}

Invoker - Client가 요청을 전달하는 매개체, 내부에서 적절한 Command에게 해당 요청을 처리하도록 위임

package BehavioralPattern.Command;

public class RemoteControl {
    private Command command;

    public void setCommand(Command command) {
        this.command = command;
    }
    
    public void doAction() {
        command.execute();
    }
}

Client & 실행결과

package BehavioralPattern.Command;

public class Client {
    public static void main(String[] args) {
        RemoteControl remoteControl = new RemoteControl();
        Light light = new Light();
        LightOnCommand lightOnCommand = new LightOnCommand(light);
        LightOffCommand lightOffCommand = new LightOffCommand(light);

        AirConditioner airConditioner = new AirConditioner();
        AirConditionerOnCommand airConditionerOnCommand = new AirConditionerOnCommand(airConditioner);
        AirConditionerOffCommand airConditionerOffCommand = new AirConditionerOffCommand(airConditioner);

        remoteControl.setCommand(lightOnCommand);
        remoteControl.doAction();
        remoteControl.setCommand(lightOffCommand);
        remoteControl.doAction();

        remoteControl.setCommand(airConditionerOnCommand);
        remoteControl.doAction();
        remoteControl.setCommand(airConditionerOffCommand);
        remoteControl.doAction();

    }
}

+ Recent posts