본문 바로가기

설계

[디자인 패턴] 커맨드 패턴 (Command Pattern) - python 예제 코드

커맨드 패턴(Command Pattern)은 객체지향 디자인 패턴의 하나로, 요청을 객체의 형태로 캡슐화하여 실행 가능한 작업으로 만드는 패턴입니다. 이 패턴은 요청을 발신자와 수신자 사이에 있는 객체들을 분리시키며, 이를 통해 요청의 종류, 매개변수, 실행 시점을 제어할 수 있게 됩니다.


1. 커맨드 패턴의 주요 구성요소

  • Command: 요청을 캡슐화하는 인터페이스. execute() 메소드를 포함합니다.
  • ConcreteCommand: Command 인터페이스를 구현한 구체적인 클래스. 실제 요청을 수행합니다.
  • Receiver: ConcreteCommand 객체에서 요청을 수행하는 객체.
  • Invoker: Command 객체를 생성하고 실행하는 객체.
  • Client: Command 객체를 생성하고 Invoker 객체에게 전달하는 객체.

2. 예제 코드

파이썬으로 구현한 간단한 예제를 통해 커맨드 패턴을 이해해 보겠습니다.

from abc import ABC, abstractmethod

# Command interface
class Command(ABC):
    @abstractmethod
    def execute(self):
        pass

# ConcreteCommand class
class LightOnCommand(Command):
    def __init__(self, light):
        self.light = light

    def execute(self):
        self.light.on()

# Receiver class
class Light:
    def on(self):
        print("Light is on")

# Invoker class
class RemoteControl:
    def __init__(self):
        self.command = None

    def set_command(self, command):
        self.command = command

    def press_button(self):
        if self.command is not None:
            self.command.execute()

# Client code
light = Light()
light_on_command = LightOnCommand(light)
remote = RemoteControl()
remote.set_command(light_on_command)
remote.press_button() # Light is on 출력


위 예제에서 Light 클래스는 Receiver 객체입니다. LightOnCommand 클래스는 Command 인터페이스를 구현한 ConcreteCommand 클래스입니다. RemoteControl 클래스는 Invoker 객체이며, set_command() 메소드로 ConcreteCommand 객체를 받아와 저장하고, press_button() 메소드에서 해당 Command 객체의 execute() 메소드를 호출합니다.

Client 코드에서는 LightOnCommand 객체를 생성하고 RemoteControl 객체에 전달합니다. 그리고나서 press_button() 메소드를 호출하여 ConcreteCommand 객체의 execute() 메소드를 실행합니다. 이렇게 하면 LightOnCommand 객체에서 요청을 캡슐화하고, RemoteControl 객체에서 해당 요청을 발신하는 방식으로 커맨드 패턴을 구현한 것입니다.

3. 장점

  • 요청을 캡슐화하여 발신자와 수신자 사이의 의존성을 분리할 수 있습니다. 이를 통해 코드의 유지보수성과 재사용성이 높아집니다.
  • 실행 가능한 작업을 객체화함으로써, 요청의 종류, 매개변수, 실행 시점 등을 동적으로 관리할 수 있습니다.
  • 새로운 ConcreteCommand 클래스를 추가하는 것으로 기능을 확장할 수 있습니다.

4. 단점

  • Command 클래스와 ConcreteCommand 클래스의 수가 늘어날 수록 코드가 복잡해질 수 있습니다.
  • 각 ConcreteCommand 클래스에서는 실행에 필요한 상태를 유지해야 하므로, 이를 관리해야 하는 추가적인 작업이 필요할 수 있습니다.

커맨드 패턴은 요청을 객체로 캡슐화하여 실행 가능한 작업으로 만듭니다. 이를 통해 코드의 유지보수성과 재사용성을 높일 수 있습니다. 단점으로는 코드의 복잡도가 증가하며, ConcreteCommand 클래스에서는 실행에 필요한 상태를 유지해야 하므로 추가적인 작업이 필요할 수 있습니다.