Posted:      Updated:

자바 디자인 패턴 스터디를 하며 ‘Java 객체 지향 디자인 패턴’ 교재를 정리한 글입니다.

커맨드 패턴(Command Pattern)

  • 실행될 기능을 캡슐화함으로써 클래스의 재사용성을 높임
  • 기능의 실행을 요구하는 호출자 클래스와 실제 기능을 수행하는 수신자 클래스 사이의 의존성을 제거함
  • 실행될 기능이 변경되더라도 호출자 클래스를 수정 없이 사용할 수 있음

커맨드 패턴 컬레보레이션

  • Command
    • 실행될 기능에 대한 인터페이스
    • 실행될 기능을 execute 메서드로 선언
  • ConcreteCommand
    • Command 의 실제 실행되는 기능 구현
  • Invoker
    • 기능의 실행을 요청하는 호출자 클래스
  • Receiver
    • ConcreteCommand 에서 execute 메서드 구현 시 필요한 클래스
    • ConcreteCommand 의 기능 실행을 위한 수신자 클래스

예시: 만능 버튼 만들기

  • 버튼이 눌렸을 때 램프의 불이 켜지는 프로그램
  • 버튼을 누르는 동작에 따라 다른 기능을 실행함
  • 구체적인 기능을 직접 구현하지 않고 클래스 외부에서 제공받아 캡슐화해서 사용

1. 알람이 동작하는 버튼

  • 처음 누를 경우 램프를 켜고 두 번 눌렀 때는 알람이 동작
  • Button: Invoker
  • Lamp, Alarm: Receiver
  • Command: Command
  • LampOnCommand, AlarmOnCommand: ConcreteCommand

전체 코드

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

public class Button {
    private Command theCommand;

    public Button(Command theCommand) {
        setCommand(theCommand);
    }

    public void setCommand(Command newCommand) {
        this.theCommand = newCommand;
    }

    public void pressed() {
        theCommand.execute();
    }
}

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

public class Alarm {
    public void start() {
        System.out.println("Alarming...");
    }
}

public class LampOnCommand implements Command{
    private Lamp theLamp;

    public LampOnCommand(Lamp thelamp) {
        this.theLamp = thelamp;
    }

    public void execute() {
        theLamp.turnOn();
    }
}

public class AlarmOnCommand implements Command{
    private Alarm theAlarm;

    public AlarmOnCommand(Alarm theAlarm) {
        this.theAlarm = theAlarm;
    }

    @Override
    public void execute() {
        theAlarm.start();
    }
}

public class Main {
    public static void main(String[] args) {
        Lamp lamp = new Lamp();
        Command lampOnCommand = new LampOnCommand(lamp);

        Button button1 = new Button(lampOnCommand);
        button1.pressed();

        Alarm alarm = new Alarm();
        Command alarmOnCommand = new AlarmOnCommand(alarm);

        Button button2 = new Button(alarmOnCommand);
        button2.pressed();

        button2.setCommand(lampOnCommand);
        button2.pressed();
    }
}

출력

Lamp On
Alarming...
Lamp On

2. 켜는 기능과 끄는 기능이 동작하는 버튼

  • 처음 누를 경우 램프를 켜고 두 번 눌렀 때는 램프가 꺼짐
  • Button: Invoker
  • Lamp: Receiver
  • Command: Command
  • LampOnCommand, LampOffCommand: ConcreteCommand

전체 코드

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

public class Button {
    private Command theCommand;

    public Button(Command theCommand) {
        setCommand(theCommand);
    }

    public void setCommand(Command newCommand) {
        this.theCommand = newCommand;
    }

    public void pressed() {
        theCommand.execute();
    }
}

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

    public void turnOff() {
        System.out.println("Lamp Off");
    }
}

public class LampOnCommand implements Command{
    private Lamp theLamp;

    public LampOnCommand(Lamp thelamp) {
        this.theLamp = thelamp;
    }

    public void execute() {
        theLamp.turnOn();
    }
}

public class LampOffCommand implements Command{
    private Lamp theLamp;

    public LampOffCommand(Lamp thelamp) {
        this.theLamp = thelamp;
    }

    public void execute() {
        theLamp.turnOff();
    }
}

public class Main {
    public static void main(String[] args) {
        Lamp lamp = new Lamp();
        Command lampOnCommand = new LampOnCommand(lamp);
        Command lampOffCommand = new LampOffCommand(lamp);

        Button button1 = new Button(lampOnCommand);
        button1.pressed();

        button1.setCommand(lampOffCommand);
        button1.pressed();
    }
}

출력

Lamp On
Lamp Off

댓글남기기