학습목표

  • 명령하다!!
  • 행위 객체화(Encapsulate Request)
    • 요청(명령)을 객체로 캡슐화하여 호출자와 수신자를 분리.
  • 호출자-수신자 결합도 낮추기
    • 요청을 수행하는 객체와 요청을 호출하는 객체를 독립적으로 설계 가능.
  • Undo/Redo, 큐잉, 예약 실행 구현
    • 요청 객체를 저장하고, 실행 취소나 재실행이 가능하도록 구조화.
  • 유연한 요청 관리
    • 명령의 실행 순서, 스케줄링, 로깅 등을 중앙 집중적으로 관리 가능.

활용상황

  • GUI 버튼, 메뉴, 액션 처리
    • 버튼 클릭, 메뉴 선택 등 이벤트를 명령 객체로 변환하여 처리.
    • 예: “저장”, “취소”, “복사” 버튼 이벤트 처리.
  • Undo/Redo 기능 구현
    • 명령을 객체로 캡슐화하여 실행 내역 저장 → 취소/재실행 가능.
    • 예: 텍스트 편집기, 그림판.
  • 작업 큐/스케줄링
    • 명령 객체를 큐에 저장하고 순차적으로 실행.
    • 예: 서버 배치 작업, 비동기 작업 처리.
  • 트랜잭션 및 로그 관리
    • 명령 객체를 로그로 남기고, 시스템 복구 시 재실행.
    • 예: 은행 계좌 입출금 트랜잭션 기록.

예제

클라이언트
   │
   ▼
Invoker (RemoteControl) ----> Command (LightOnCommand) ----> Receiver (Light)
                                execute()                        on()
  • Command
public interface Command {
    void execute();
}
  • Receiver
public class Light {

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

    public void off() {
        System.out.println("Light is OFF");
    }
}
  • ConcreteCommand
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();
    }
}
  • Invoker
public class RemoteControl {
    private Command command;

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

    public void pressButton() {
        command.execute();
    }
}
  • 실행
public class Main {

    public static void main(String[] args) {
        Light livingRoomLight = new Light();

        Command lightOn = new LightOnCommand(livingRoomLight);
        Command lightOff = new LightOffCommand(livingRoomLight);

        RemoteControl remote = new RemoteControl();

        remote.setCommand(lightOn);
        remote.pressButton(); // Light is ON

        remote.setCommand(lightOff);
        remote.pressButton(); // Light is OFF
    }
}

 

  • 클라이언트가 Invoker에 LightOnCommand를 설정.
  • Invoker가 pressButton() → command.execute() 호출.
  • ConcreteCommand(LightOnCommand)가 Receiver(Light). on() 호출.
  • Light가 실제로 켜짐.

마무리

객체를 받아서 명령만하는 구조 같다. 

+ Recent posts