ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 행동(Behavioral) - 커맨드(Command) 패턴
    Java/디자인패턴 2024. 11. 21. 09:45
    반응형

    커맨드(Command) 패턴

    커맨드(Command) 패턴행동(Behavioral) 패턴에 속합니다. 이 패턴은 요청을 객체로 캡슐화하여 사용자가 요청의 매개변수화, 큐잉(queuing), 로깅(logging) 등을 수행할 수 있도록 합니다. 또한, 작업 실행 취소(Undo)와 재실행(Redo) 기능을 쉽게 구현할 수 있도록 설계됩니다.


    커맨드 패턴의 특징

    1. 명령 캡슐화:
      • 요청(작업)을 하나의 객체로 캡슐화하여 메서드 호출을 명령 객체로 처리합니다.
    2. 작업 실행 취소 및 재실행 지원:
      • 명령의 상태를 저장하여 Undo와 Redo를 쉽게 구현할 수 있습니다.
    3. 클라이언트와 요청 분리:
      • 명령을 요청하는 클라이언트와 실제로 요청을 실행하는 리시버(Receiver)를 분리합니다.

    커맨드 패턴 구성요소

    1. Command (명령):
      • 실행될 작업을 캡슐화하는 인터페이스 또는 추상 클래스입니다.
    2. ConcreteCommand (구체적인 명령):
      • Command를 구현하며 특정 요청에 대한 작업을 정의합니다.
    3. Receiver (수신자):
      • 명령을 실행하는 실제 객체입니다.
    4. Invoker (요청자):
      • 명령 객체를 호출하는 역할을 합니다.
    5. Client (클라이언트):
      • 명령 객체를 생성하고 Invoker와 Receiver를 설정합니다.

    JAVA 예제

    1. Command 인터페이스

    // Command 인터페이스
    interface Command {
        void execute();
        void undo();
    }

     

     

    2. Receiver 구현

    // Receiver: 작업을 수행하는 실제 객체
    class Light {
        private boolean isOn = false;
    
        public void turnOn() {
            isOn = true;
            System.out.println("Light is ON");
        }
    
        public void turnOff() {
            isOn = false;
            System.out.println("Light is OFF");
        }
    }

     

     

    3. ConcreteCommand 구현

    // Light On Command
    class LightOnCommand implements Command {
        private Light light;
    
        public LightOnCommand(Light light) {
            this.light = light;
        }
    
        @Override
        public void execute() {
            light.turnOn();
        }
    
        @Override
        public void undo() {
            light.turnOff();
        }
    }
    
    // Light Off Command
    class LightOffCommand implements Command {
        private Light light;
    
        public LightOffCommand(Light light) {
            this.light = light;
        }
    
        @Override
        public void execute() {
            light.turnOff();
        }
    
        @Override
        public void undo() {
            light.turnOn();
        }
    }

     

     

    4. Invoker 구현

    // Invoker: 명령을 요청하는 객체
    class RemoteControl {
        private Command command;
    
        public void setCommand(Command command) {
            this.command = command;
        }
    
        public void pressButton() {
            command.execute();
        }
    
        public void pressUndo() {
            command.undo();
        }
    }

     

     

    5. 사용 예시

    public class CommandPatternExample {
        public static void main(String[] args) {
            // Receiver 생성
            Light livingRoomLight = new Light();
    
            // Command 객체 생성
            Command lightOn = new LightOnCommand(livingRoomLight);
            Command lightOff = new LightOffCommand(livingRoomLight);
    
            // Invoker 설정
            RemoteControl remote = new RemoteControl();
    
            // Light On
            remote.setCommand(lightOn);
            remote.pressButton();  // Output: Light is ON
            remote.pressUndo();    // Output: Light is OFF
    
            // Light Off
            remote.setCommand(lightOff);
            remote.pressButton();  // Output: Light is OFF
            remote.pressUndo();    // Output: Light is ON
        }
    }

     

     

    실행 결과

    Light is ON
    Light is OFF
    Light is OFF
    Light is ON

     


    커맨드 패턴의 활용 사례

    1. UI 버튼 및 메뉴:
      • GUI 애플리케이션에서 버튼 클릭이나 메뉴 선택 동작을 명령으로 처리.
    2. 작업 실행 취소 및 재실행:
      • 텍스트 편집기, 그래픽 소프트웨어 등에서 Undo/Redo 기능 구현.
    3. 요청 큐 관리:
      • 요청을 큐에 넣어 비동기로 처리하거나 실행 순서를 조정.
    4. 매크로 실행:
      • 여러 명령을 조합하여 하나의 작업으로 실행.

    장점

    1. 요청의 캡슐화:
      • 클라이언트와 수신자를 분리하여 독립적인 시스템 설계 가능.
    2. Undo/Redo 구현 용이:
      • 명령 객체에 실행 전 상태를 저장하여 실행 취소가 쉬워짐.
    3. 확장성 증가:
      • 새로운 명령을 쉽게 추가할 수 있음.
    4. 명령 큐 관리:
      • 명령을 큐에 저장하거나 요청을 기록/재실행할 수 있음.

    단점

    1. 복잡성 증가:
      • 명령 객체, 수신자, 요청자를 별도로 생성해야 하므로 설계가 복잡해질 수 있음.
    2. 많은 클래스 필요:
      • 작업마다 Command 클래스를 생성해야 하므로 클래스 수가 늘어남.
    반응형

    댓글

Designed by Tistory.