HEAD FIRST设计模式-命令模式

定义

将请求封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式支持可撤销的操作。

优点

命令模式将发出请求的对象和执行请求的对象解耦。在被解耦的两者之间通过命令对象进行沟通,命令对象封装了接收者的一个或者一组动作。
一个命令对象通过在特定的接收者上绑定一组动作来封装一个请求。命令对象将动作和接收者包进对象中,这个对象只暴露一个execute()方法。

python代码如下

from abc import abstractmethod
from enum import Enum


class Command:
    def __init__(self):
        pass

    @abstractmethod
    def execute(self):
        pass

    @abstractmethod
    def undo(self):
        pass


class CeilingFanSpeed(Enum):
    HIGH = 3
    MEDIUM = 2
    LOW = 1
    OFF = 0


class CeilingFan:
    def __init__(self,location):
        self.location = location
        self.speed = CeilingFanSpeed.OFF

    def high(self):
        self.speed = CeilingFanSpeed.HIGH
        print(self.location+":celling fan set high speed!")

    def medium(self):
        self.speed = CeilingFanSpeed.MEDIUM
        print(self.location+":celling fan set medium speed!")

    def low(self):
        self.speed = CeilingFanSpeed.LOW
        print(self.location + ":celling fan set low speed!")

    def off(self):
        self.speed = CeilingFanSpeed.OFF
        print(self.location + ":celling fan set off!")

    def get_speed(self):
        return self.speed


class CeilingFanHighCommand(Command):
    def __init__(self,ceiling_fan):
        self.ceiling_fan = ceiling_fan
        self.prev_speed = None

    def execute(self):
        self.prev_speed = self.ceiling_fan.get_speed()
        self.ceiling_fan.high()

    def undo(self):
        if self.prev_speed == CeilingFanSpeed.LOW:
            self.ceiling_fan.low()
        elif self.prev_speed == CeilingFanSpeed.MEDIUM:
            self.ceiling_fan.medium()
        elif self.prev_speed == CeilingFanSpeed.HIGH:
            self.ceiling_fan.high()
        elif self.prev_speed == CeilingFanSpeed.OFF:
            self.ceiling_fan.off()


class CeilingFanMediumCommand(Command):
    def __init__(self,ceiling_fan):
        self.ceiling_fan = ceiling_fan
        self.prev_speed = None

    def execute(self):
        self.prev_speed = self.ceiling_fan.get_speed()
        self.ceiling_fan.medium()

    def undo(self):
        if self.prev_speed == CeilingFanSpeed.LOW:
            self.ceiling_fan.low()
        elif self.prev_speed == CeilingFanSpeed.MEDIUM:
            self.ceiling_fan.medium()
        elif self.prev_speed == CeilingFanSpeed.HIGH:
            self.ceiling_fan.high()
        elif self.prev_speed == CeilingFanSpeed.OFF:
            self.ceiling_fan.off()


class CeilingFanLowCommand(Command):
    def __init__(self,ceiling_fan):
        self.ceiling_fan = ceiling_fan
        self.prev_speed = None

    def execute(self):
        self.prev_speed = self.ceiling_fan.get_speed()
        self.ceiling_fan.low()

    def undo(self):
        if self.prev_speed == CeilingFanSpeed.LOW:
            self.ceiling_fan.low()
        elif self.prev_speed == CeilingFanSpeed.MEDIUM:
            self.ceiling_fan.medium()
        elif self.prev_speed == CeilingFanSpeed.HIGH:
            self.ceiling_fan.high()
        elif self.prev_speed == CeilingFanSpeed.OFF:
            self.ceiling_fan.off()


class CeilingFanOffCommand(Command):
    def __init__(self,ceiling_fan):
        self.ceiling_fan = ceiling_fan
        self.prev_speed = None

    def execute(self):
        self.prev_speed = self.ceiling_fan.get_speed()
        self.ceiling_fan.off()

    def undo(self):
        if self.prev_speed == CeilingFanSpeed.LOW:
            self.ceiling_fan.low()
        elif self.prev_speed == CeilingFanSpeed.MEDIUM:
            self.ceiling_fan.medium()
        elif self.prev_speed == CeilingFanSpeed.HIGH:
            self.ceiling_fan.high()
        elif self.prev_speed == CeilingFanSpeed.OFF:
            self.ceiling_fan.off()


class Light:
    def __init__(self,location):
        self.location = location

    def on(self):
        print(self.location+":light on")

    def off(self):
        print(self.location+":light off")


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

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

    def undo(self):
        self.light.off()


class LightOffCommand(Command):
    def __init__(self, light):
        self.light = light

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

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


class Stereo:
    def __init__(self,location):
        self.location = location

    def on(self):
        print(self.location+":stereo on")

    def off(self):
        print(self.location+":stereo off")

    def set_cd(self):
        print("stereo set CD")

    def set_volume(self,volume):
        print("stereo set volume to:"+str(volume))


class StereoOnCommand(Command):
    def __init__(self,stereo):
        self.stereo = stereo

    def execute(self):
        self.stereo.on()
        self.stereo.set_cd()
        self.stereo.set_volume(20)

    def undo(self):
        self.stereo.off()


class StereoOffCommand(Command):
    def __init__(self,stereo):
        self.stereo = stereo

    def execute(self):
        self.stereo.off()

    def undo(self):
        self.stereo.on()


class NoCommand(Command):
    def __init__(self):
        pass

    def execute(self):
        print("NoCommand execute")

    def undo(self):
        print("NoCommand undo")


class RemoteControl:
    def __init__(self):
        self.on_commands = []
        self.off_commands = []
        self.undo_commands = NoCommand()
        for i in range(7):
            self.on_commands.append(NoCommand())
            self.off_commands.append(NoCommand())

    def set_command(self,slot,on_command,off_command):
        self.on_commands[slot] = on_command
        self.off_commands[slot] = off_command

    def on_button_pressed(self,slot):
        self.on_commands[slot].execute()
        self.undo_commands = self.on_commands[slot]

    def off_button_pressed(self,slot):
        self.off_commands[slot].execute()
        self.undo_commands = self.off_commands[slot]

    def undo_button_pressed(self):
        self.undo_commands.undo()


def test_command():
    remote_control = RemoteControl()

    light = Light("Living room")
    light_on_cmd = LightOnCommand(light)
    light_off_cmd = LightOffCommand(light)
    remote_control.set_command(0,light_on_cmd,light_off_cmd)
    remote_control.on_button_pressed(0)
    remote_control.off_button_pressed(0)

    stereo = Stereo("Living room")
    stereo_on_cmd = StereoOnCommand(stereo)
    stereo_off_cmd = StereoOffCommand(stereo)
    remote_control.set_command(1, stereo_on_cmd, stereo_off_cmd)
    remote_control.on_button_pressed(1)
    remote_control.off_button_pressed(1)


def test_command2():
    remote_control = RemoteControl()

    ceiling_fan = CeilingFan("Living room")
    ceiling_fan_high_cmd = CeilingFanHighCommand(ceiling_fan)
    ceiling_fan_medium_cmd = CeilingFanMediumCommand(ceiling_fan)
    ceiling_fan_low_cmd = CeilingFanLowCommand(ceiling_fan)
    ceiling_fan_off_cmd = CeilingFanOffCommand(ceiling_fan)

    remote_control.set_command(0, ceiling_fan_low_cmd, ceiling_fan_off_cmd)
    remote_control.set_command(1, ceiling_fan_medium_cmd, ceiling_fan_off_cmd)
    remote_control.set_command(2, ceiling_fan_high_cmd, ceiling_fan_off_cmd)

    remote_control.on_button_pressed(0)
    remote_control.on_button_pressed(1)

    # remote_control.undo_button_pressed()
    # print("")

    # remote_control.off_button_pressed(1)
    remote_control.on_button_pressed(2)
    remote_control.undo_button_pressed()
    remote_control.off_button_pressed(2)


if __name__ == "__main__":
    test_command2()

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值