design_pattern_command命令模式

命令模式

  • GOF定义:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。
  • Head First设计模式定义:将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。
  • 简单来说:命令模式就是封装调用/封装请求

Python例子3

class Command:
    # 指令抽象类
    
    def execute(self):
        pass

    def undo(self):
        pass

class Receiver:
    def __init__(self):
        self.m_Command = []
        self.m_CommandDone = []
    
    def AddCommand(self, cmd):
        self.m_Command.append(cmd)
    
    def execute(self):
        for cmd in self.m_Command:
            cmd.execute()
            self.m_CommandDone.append(cmd)
    
    def undo(self):
        if self.m_CommandDone:
            cmd = self.m_CommandDone.pop()
            cmd.undo()

class LightOnCommand(Command):
    # 开灯
    def __init__(self, pLight):
        self.m_Light = pLight
    
    def execute(self):
        self.m_Light.On()
    
    def undo(self):
        self.m_Light.Off()

class LightOffCommand(Command):
    # 关灯
    def __init__(self, pLight):
        self.m_Light = pLight
    
    def execute(self):
        self.m_Light.Off()
    
    def undo(self):
        self.m_Light.On()

class Light(object):
    def __init__(self, sName):
        self.m_LightName = sName
    
    def On(self):
        print("[%s] %s" % (self.m_LightName,"Light On"))
    
    def Off(self):
        print("[%s] %s" % (self.m_LightName,"Light Off"))

if __name__ == '__main__':
    receiver = Receiver()

    livingRoomLight = Light("livingRoomLight")
    bedRoomLight = Light("bedRoomLight")
    
    
    receiver.AddCommand(LightOnCommand(livingRoomLight))
    receiver.AddCommand(LightOnCommand(bedRoomLight))
    receiver.AddCommand(LightOffCommand(livingRoomLight))
    
    receiver.execute()
    receiver.undo()
    
    #[livingRoomLight] Light On
    #[bedRoomLight] Light On
    #[livingRoomLight] Light Off
    #[livingRoomLight] Light On

优点 1

  • 类间解耦
    调用者角色与接收者角色之间没有任何依赖关系,调用者实现功能时只需要调用Command抽象类的execute方法就可以,不需要了解到底是哪个接收者执行。
  • 可拓展性
    Command的子类可以非常容易地扩展,而调用者Invoker和高层次的模块Client不缠上严重的代码耦合
  • 命令模式结合其他模式会更优秀
    命令模式可以结合责任链模式,实现命令族解析任务;结合模板方法模式,则可以减少Command子类的膨胀问题。

缺点 2

  • 每个单独的指令都是一个具体指令(ConcreteCommand)类,从而增加了需要实现和维护的类的数量。

参考

  • [1] 《设计模式之禅》 - 命令模式的优点
  • [2] 《python设计模式》 - 命令模式的缺点
  • [3] 《Head First设计模式》 - 例子参考文章遥控器

你可能感兴趣的:(编程语言)