행동 패턴: 커맨드 패턴

xellos·2022년 4월 13일
0

디자인 패턴

목록 보기
17/20

소개

요청을 캡슐화하여 호출자(invoker)와 수신자(receiver)를 분리하는 패턴이다. 요청을 처리하는 방법이 바뀌더라도 호출자의 코드는 변경되지 않는다.

1) 장점

  1. 기존 코드를 변경하지 않고 새로운 커맨드를 만들 수 있다.
  2. 수신자의 코드가 변경되어도 호출자(Invoker)의 코드는 변경되지 않는다.
  3. 커맨드 객체를 로깅, DB에 저장, 네트워크로 전송하는 등 다양한 방법으로 활용할 수도 있다.

2) 단점

  1. 코드가 복잡하고 클래스가 많아진다.

구현

1) Receiver 정의

Light

public class Light {

	private boolean isOn;
    
    public void on() {
    	System.out.println("불을 켭니다.");
        this.isOn = true;
    }
    
    public void off() {
    	System.out.println("불을 끕니다.");
        this.isOn = false;
    }
    
    public boolean isOn() {
    	return this.isOn;
    }
}

2) 커맨드 인터페이스 정의

public interface Command {
	void execute();
    void undo();
}

3) 커맨드 인터페이스를 구현하는 클래스 정의

LightOffCommand

public class LightOffCommand implements Command {

	private Light light;
    
	public LightOffCommand(Light light) {
    	this.light = light;
    }
    
    @Override
    public void execute() {
    	light.off();
    }
    
    @Override
    public void undo() {
    	new LightOnCommand(this.light).execute();
    }
}

LightOnCommand

public class LightOnCommand implements Command {

	private Light light;

	public LightOnCommand(Light light) {
    	this.light = light;
    }
    
    @Override
    public void execute() {
    	light.on();
    }
    
    @Override
    public void undo() {
    	new LightOffCommand(this.light).execute();
    }
}

사용

Button (Invoker)

public class Button {
	
    private Stack<Command> commands = new Stack<>();
    
    public void press(Command command) {
    	command.execute();
        commands.push(command);
    }
    
    public void undo() {
    	if(!commands.isEmpty()) {
        	Command command = Commands.pop();
            command.undo();
        }
    }
    
    public static void main(String[] args) {
    	Button button = new Button();
        button.press(new LightOnCommand(new Light()));
        button.undo();
    }
}

0개의 댓글