커맨드 패턴

런던행·2020년 8월 9일
0

커맨드 패턴은 객체가 특정 기능을 바로 수행하거나 나중에 트리거할 때 필요한 모든 정보를 캡슐화하는 행동 패턴이다. 캡슐화하는 정보는 다음과 같다.

  • 메소드
  • 메소드를 소유하는 객체
  • 메소드 인자

커맨드 패턴 구성요소

Command, Receiver, Invoker, Client 클래스로 구성된다.

  • Command 객체는 Receiver 객체에 대해 알고 있으면 Receiver 객체의 함수를 호출한다.
  • Receiver 함수의 인자는 Command객체에 저장돼 있다.
  • Invoker는 명령을 수행한다.
  • Client는 Command객체를 생성하고 Receiver를 정한다.

커맨드 패턴의 목적은 다음과 같다

  • 요청을 객체 속에 캡슐화 한다.
  • 클라이언트의 다양한 요청을 매개변수화 한다.
  • 요청을 큐에 저장한다.
  • 객체지향 콜백을 지원한다.

커맨드 패턴은 다음과 같은 상황에 적합하다.

  • 수행할 명령에 따라 객체를 변수화 할 때
  • 요청을 큐에 저장하고 각기 다른 시점에 수행해야 하는 경우
  • 작은 단위의 연산을 기반으로 하는 상위 연산을 만들 때

커맨드 패턴 실제 활용

증권거래소를 커맨드 패턴으로 구현해보자. 일반적으로 고객이 주식을 직접 사거나 팔지 않고 에이전트나 브로커가 고객과 거래소 사이에서 중재자 역할을 한다. 중개사는 고객의 요청을 받아 채임지고 거래소에 전달해 처리한다.

클래스 설계

커맨드 패턴에는 Command, ConcreateCommand, Invoker, Receiver 등 총 4개 객체로 구성된다. 주식매매 시나리오에서 우선 고객의 주문을 나타내는 Order인터페이스를 작성한다. 다음으로 주식을 매매하는 ConcreateCommand 클래스를 작성한다. 증권거래소를 대표하는 클래스도 필요하다. Receiver 클래스는 실제 주식을 거래를 담당하고 Invoker인 중개사는 거래를 개시하고 Receiver에 처리를 요청한다.

  • Order클래스는 Command 객체를 나타낸다.
  • Order클래스는 파이썬의 추상 기본 클래스인 인터페이스며 ConcreateCommand는 이를 기반으로 세부 로직을 구현한다.
  • execute()메소는 ConcrateCommand클래스가 Order클래스를 실행하는 추상 메소스다.
from abc import ABCMeta, abstractmethod

# Command
class Order(metaclass=ABCMeta):
    @abstractmethod
    def execute(self):
        pass

# ConcreateCommand
class BuyStockOrder(Order):
    def __init__(self, stock):
        self.stock = stock

    def execute(self):
        self.stock.buy()

class SellStockOrder(Order):
    def __init__(self, stock):
        self.stock = stock

    def execute(self):
        self.stock.sell()

# Receiver : 증권거래 시스템
class StockTrade:
    def buy(self):
        print("Buy stocks")

    def sell(self):
        print("Sell stocks")

# Invoker: 에이전트
class Agent:
    def __init__(self):
        self.__orderQueue= []

    def placeOrder(self, order):
        self.__orderQueue.append(order)
        order.execute()


if __name__ == '__main__':
    #client
    stock = StockTrade()
    buyStock = BuyStockOrder(stock)
    sellStock = SellStockOrder(stock)

    #Invoker
    agent = Agent()
    agent.placeOrder(buyStock)
    agent.placeOrder(sellStock)

Buy stocks
Sell stocks

profile
unit test, tdd, bdd, laravel, django, android native, vuejs, react, embedded linux, typescript

0개의 댓글