当前位置: 首页 > ai >正文

基于Python学习《Head First设计模式》第六章 命令模式

遥控器项目

在这里插入图片描述
在这里插入图片描述

实现思路

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

实现类图

在这里插入图片描述
在这里插入图片描述

再次梳理

在这里插入图片描述

代码实现

在这里插入图片描述

class RemoteControl:"""遥控器"""on_commands: List[Command]off_commands: List[Command]def __init__(self):self.on_commands = []self.off_commands = []no_command = NoCommand()for _ in range(7):self.on_commands.append(no_command)self.off_commands.append(no_command)def set_command(self, slot: int, on_command: Command, off_command: Command):self.on_commands[slot] = on_commandself.off_commands[slot] = off_commanddef on_button_was_pushed(self, slot: int):self.on_commands[slot].excute()def off_button_was_pushed(self, slot: int):self.off_commands[slot].excute()def __str__(self):buffer_str = []for i in range(len(self.on_commands)):buffer_str.append(f'[卡槽{i + 1}]{self.on_commands[i].__class__.__qualname__}\t{self.off_commands[i].__class__.__qualname__}')return "\n".join(buffer_str)

在这里插入图片描述

class LightOffCommand(Command):light: Lightdef __init__(self, light: Light):self.light = lightdef excute(self):self.light.off()def undo(self):passclass StereoOnWithCDCommand(Command):stereo: Stereodef __init__(self, stereo: Stereo):self.stereo = stereodef excute(self):self.stereo.on()self.stereo.set_cd()self.stereo.set_volume(11)def undo(self):pass

在这里插入图片描述

if __name__ == '__main__':remote_control = RemoteControl()living_room_light = Light("Living Room light")kitchen_light = Light("Kitchen light")stereo = Stereo("Living Room Stereo")living_room_light_on = LightOnCommand(living_room_light)living_room_light_off = LightOffCommand(living_room_light)kitchen_light_on = LightOnCommand(kitchen_light)kitchen_light_off = LightOffCommand(kitchen_light)stereo_on = StereoOnWithCDCommand(stereo)stereo_off = StereoOffWithCDCommand(stereo)remote_control.set_command(0, living_room_light_on, living_room_light_off)remote_control.set_command(1, kitchen_light_on, kitchen_light_off)remote_control.set_command(2, stereo_on, stereo_off)print(remote_control)print()remote_control.on_button_was_pushed(0)remote_control.off_button_was_pushed(0)remote_control.on_button_was_pushed(1)remote_control.off_button_was_pushed(1)remote_control.on_button_was_pushed(2)remote_control.off_button_was_pushed(2)

设计全貌

在这里插入图片描述

完整代码

与书上的代码略有不同,整体结构是一样的。书上是吊扇,我这里是音响。

from abc import ABCMeta, abstractmethod, ABC
from typing import Listclass Command(ABC):@abstractmethoddef excute(self):pass@abstractmethoddef undo(self):passclass NoCommand(Command):def excute(self):passdef undo(self):passclass Light:"""电灯"""name: strdef __init__(self, name):self.name = namedef off(self):print(f'{self.name} is off.')def on(self):print(f'{self.name} is on.')class LightOnCommand(Command):light: Lightdef __init__(self, light: Light):self.light = lightdef excute(self):self.light.on()def undo(self):print('撤销操作,', end='')self.light.off()class LightOffCommand(Command):light: Lightdef __init__(self, light: Light):self.light = lightdef excute(self):self.light.off()def undo(self):print('撤销操作,', end='')self.light.on()class Stereo:"""音响"""name: strdef __init__(self, name):self.name = namedef off(self):print(f'{self.name} is off.')def on(self):print(f'{self.name} is on.')def set_cd(self):print(f'{self.name} is set for CD input.')def set_volume(self, volume: int):print(f'{self.name} volume set to {volume}.')class StereoOnWithCDCommand(Command):stereo: Stereodef __init__(self, stereo: Stereo):self.stereo = stereodef excute(self):self.stereo.on()self.stereo.set_cd()self.stereo.set_volume(11)def undo(self):print('撤销操作,', end='')self.stereo.off()class StereoOffWithCDCommand(Command):stereo: Stereodef __init__(self, stereo: Stereo):self.stereo = stereodef excute(self):self.stereo.off()def undo(self):print('撤销操作,', end='')self.stereo.on()class RemoteControl:"""遥控器"""on_commands: List[Command]off_commands: List[Command]undo_command: Commanddef __init__(self):self.on_commands = []self.off_commands = []no_command = NoCommand()for _ in range(7):self.on_commands.append(no_command)self.off_commands.append(no_command)self.undo_command = no_commanddef set_command(self, slot: int, on_command: Command, off_command: Command):self.on_commands[slot] = on_commandself.off_commands[slot] = off_commanddef on_button_was_pushed(self, slot: int):self.on_commands[slot].excute()self.undo_command = self.on_commands[slot]def off_button_was_pushed(self, slot: int):self.off_commands[slot].excute()self.undo_command = self.off_commands[slot]def undo_button_was_pushed(self):self.undo_command.undo()def __str__(self):buffer_str = []for i in range(len(self.on_commands)):buffer_str.append(f'[卡槽{i + 1}]{self.on_commands[i].__class__.__qualname__}\t{self.off_commands[i].__class__.__qualname__}')return "\n".join(buffer_str)if __name__ == '__main__':remote_control = RemoteControl()living_room_light = Light("Living Room light")kitchen_light = Light("Kitchen light")stereo = Stereo("Living Room Stereo")living_room_light_on = LightOnCommand(living_room_light)living_room_light_off = LightOffCommand(living_room_light)kitchen_light_on = LightOnCommand(kitchen_light)kitchen_light_off = LightOffCommand(kitchen_light)stereo_on = StereoOnWithCDCommand(stereo)stereo_off = StereoOffWithCDCommand(stereo)remote_control.set_command(0, living_room_light_on, living_room_light_off)remote_control.set_command(1, kitchen_light_on, kitchen_light_off)remote_control.set_command(2, stereo_on, stereo_off)print(remote_control)print()remote_control.on_button_was_pushed(0)remote_control.off_button_was_pushed(0)remote_control.undo_button_was_pushed()remote_control.on_button_was_pushed(1)remote_control.undo_button_was_pushed()remote_control.off_button_was_pushed(1)remote_control.off_button_was_pushed(2)remote_control.on_button_was_pushed(2)remote_control.undo_button_was_pushed()"""运行结果:
[卡槽1]LightOnCommand	LightOffCommand
[卡槽2]LightOnCommand	LightOffCommand
[卡槽3]StereoOnWithCDCommand	StereoOffWithCDCommand
[卡槽4]NoCommand	NoCommand
[卡槽5]NoCommand	NoCommand
[卡槽6]NoCommand	NoCommand
[卡槽7]NoCommand	NoCommandLiving Room light is on.
Living Room light is off.
撤销操作,Living Room light is on.
Kitchen light is on.
撤销操作,Kitchen light is off.
Kitchen light is off.
Living Room Stereo is off.
Living Room Stereo is on.
Living Room Stereo is set for CD input.
Living Room Stereo volume set to 11.
撤销操作,Living Room Stereo is off.
"""

添加撤销操作


from abc import ABCMeta, abstractmethod, ABC
from typing import Listclass Command(ABC):@abstractmethoddef excute(self):pass@abstractmethoddef undo(self):passclass NoCommand(Command):def excute(self):passdef undo(self):passclass Stereo:"""音响"""name: strHIGH = 90MEDIUM = 40LOW = 10OFF = 0_volume: intdef __init__(self, name):self.name = nameself._volume = Stereo.OFFdef off(self):print(f'{self.name} is off.')def on(self):print(f'{self.name} is on.')def set_cd(self):print(f'{self.name} is set for CD input.')def set_volume(self, volume: int):self._volume = volumeprint(f'{self.name} volume set to {volume}.')def get_volume(self):return self._volumedef volume_high(self):print(f'音量设置为{Stereo.HIGH}')self._volume = Stereo.HIGHdef volume_medium(self):print(f'音量设置为{Stereo.MEDIUM}')self._volume = Stereo.MEDIUMdef volume_low(self):print(f'音量设置为{Stereo.LOW}')self._volume = Stereo.LOWclass StereoOnWithCDCommand(Command):stereo: Stereopre_volume: intdef __init__(self, stereo: Stereo):self.stereo = stereodef excute(self):self.pre_volume = self.stereo.get_volume()self.stereo.on()self.stereo.set_cd()self.stereo.set_volume(Stereo.MEDIUM)def undo(self):print('撤销操作,', end='')class StereoHighVolumeWithCDCommand(Command):pre_volume: intdef __init__(self, stereo: Stereo):self.stereo = stereodef excute(self):self.pre_volume = self.stereo.get_volume()self.stereo.volume_high()def undo(self):print('撤销操作,', end='')if self.pre_volume == Stereo.HIGH:self.stereo.volume_high()elif self.pre_volume == Stereo.MEDIUM:self.stereo.volume_medium()elif self.pre_volume == Stereo.LOW:self.stereo.volume_low()else:self.stereo.off()class StereoLowVolumeWithCDCommand(Command):pre_volume: intdef __init__(self, stereo: Stereo):self.stereo = stereodef excute(self):self.pre_volume = self.stereo.get_volume()self.stereo.volume_low()def undo(self):print('撤销操作,', end='')if self.pre_volume == Stereo.HIGH:self.stereo.volume_high()elif self.pre_volume == Stereo.MEDIUM:self.stereo.volume_medium()elif self.pre_volume == Stereo.LOW:self.stereo.volume_low()else:self.stereo.off()class StereoOffWithCDCommand(Command):stereo: Stereodef __init__(self, stereo: Stereo):self.stereo = stereodef excute(self):self.stereo.off()def undo(self):print('撤销操作,', end='')self.stereo.on()class RemoteControlWithUndo:"""遥控器"""on_commands: List[Command]off_commands: List[Command]undo_command: Commanddef __init__(self):self.on_commands = []self.off_commands = []no_command = NoCommand()for _ in range(7):self.on_commands.append(no_command)self.off_commands.append(no_command)self.undo_command = no_commanddef set_command(self, slot: int, on_command: Command, off_command: Command):self.on_commands[slot] = on_commandself.off_commands[slot] = off_commanddef on_button_was_pushed(self, slot: int):self.on_commands[slot].excute()self.undo_command = self.on_commands[slot]def off_button_was_pushed(self, slot: int):self.off_commands[slot].excute()self.undo_command = self.off_commands[slot]def undo_button_was_pushed(self):self.undo_command.undo()def __str__(self):buffer_str = []for i in range(len(self.on_commands)):buffer_str.append(f'[卡槽{i + 1}]{self.on_commands[i].__class__.__qualname__}\t{self.off_commands[i].__class__.__qualname__}')return "\n".join(buffer_str)if __name__ == '__main__':remote_control = RemoteControlWithUndo()stereo = Stereo('音响')stereo_off = StereoOffWithCDCommand(stereo)stereo_high_volume = StereoHighVolumeWithCDCommand(stereo)stereo_low_volume = StereoLowVolumeWithCDCommand(stereo)remote_control.set_command(0, stereo_high_volume, stereo_off)remote_control.set_command(1, stereo_low_volume, stereo_off)print(remote_control)remote_control.on_button_was_pushed(0)remote_control.off_button_was_pushed(0)remote_control.undo_button_was_pushed()remote_control.on_button_was_pushed(1)remote_control.undo_button_was_pushed()"""运行结果:
[卡槽1]StereoHighVolumeWithCDCommand	StereoOffWithCDCommand
[卡槽2]StereoLowVolumeWithCDCommand	StereoOffWithCDCommand
[卡槽3]NoCommand	NoCommand
[卡槽4]NoCommand	NoCommand
[卡槽5]NoCommand	NoCommand
[卡槽6]NoCommand	NoCommand
[卡槽7]NoCommand	NoCommand
音量设置为90
音响 is off.
撤销操作,音响 is on.
音量设置为10
撤销操作,音量设置为90
"""

批量操作

使用宏命令

from abc import ABCMeta, abstractmethod, ABC
from typing import Listclass Command(ABC):@abstractmethoddef excute(self):pass@abstractmethoddef undo(self):passclass NoCommand(Command):def excute(self):passdef undo(self):passclass MacroCommand(Command):commands: List[Command]def __init__(self, commands: List[Command]):self.commands = commandsdef excute(self):for command in self.commands:command.excute()def undo(self):for command in self.commands:command.undo()class Light:"""电灯"""name: strdef __init__(self, name):self.name = namedef off(self):print(f'{self.name} is off.')def on(self):print(f'{self.name} is on.')class LightOnCommand(Command):light: Lightdef __init__(self, light: Light):self.light = lightdef excute(self):self.light.on()def undo(self):print('撤销操作,', end='')self.light.off()class LightOffCommand(Command):light: Lightdef __init__(self, light: Light):self.light = lightdef excute(self):self.light.off()def undo(self):print('撤销操作,', end='')self.light.on()class Stereo:"""音响"""name: strdef __init__(self, name):self.name = namedef off(self):print(f'{self.name} is off.')def on(self):print(f'{self.name} is on.')def set_cd(self):print(f'{self.name} is set for CD input.')def set_volume(self, volume: int):print(f'{self.name} volume set to {volume}.')class StereoOnWithCDCommand(Command):stereo: Stereodef __init__(self, stereo: Stereo):self.stereo = stereodef excute(self):self.stereo.on()self.stereo.set_cd()self.stereo.set_volume(11)def undo(self):print('撤销操作,', end='')self.stereo.off()class StereoOffWithCDCommand(Command):stereo: Stereodef __init__(self, stereo: Stereo):self.stereo = stereodef excute(self):self.stereo.off()def undo(self):print('撤销操作,', end='')self.stereo.on()class RemoteControl:"""遥控器"""on_commands: List[Command]off_commands: List[Command]undo_command: Commanddef __init__(self):self.on_commands = []self.off_commands = []no_command = NoCommand()for _ in range(7):self.on_commands.append(no_command)self.off_commands.append(no_command)self.undo_command = no_commanddef set_command(self, slot: int, on_command: Command, off_command: Command):self.on_commands[slot] = on_commandself.off_commands[slot] = off_commanddef on_button_was_pushed(self, slot: int):self.on_commands[slot].excute()self.undo_command = self.on_commands[slot]def off_button_was_pushed(self, slot: int):self.off_commands[slot].excute()self.undo_command = self.off_commands[slot]def undo_button_was_pushed(self):self.undo_command.undo()def __str__(self):buffer_str = []for i in range(len(self.on_commands)):buffer_str.append(f'[卡槽{i + 1}]{self.on_commands[i].__class__.__qualname__}\t{self.off_commands[i].__class__.__qualname__}')return "\n".join(buffer_str)if __name__ == '__main__':remote_control = RemoteControl()living_room_light = Light("Living Room light")kitchen_light = Light("Kitchen light")stereo = Stereo("Living Room Stereo")living_room_light_on = LightOnCommand(living_room_light)living_room_light_off = LightOffCommand(living_room_light)kitchen_light_on = LightOnCommand(kitchen_light)kitchen_light_off = LightOffCommand(kitchen_light)stereo_on = StereoOnWithCDCommand(stereo)stereo_off = StereoOffWithCDCommand(stereo)remote_control.set_command(0, living_room_light_on, living_room_light_off)remote_control.set_command(1, kitchen_light_on, kitchen_light_off)remote_control.set_command(2, stereo_on, stereo_off)party_on_macro = [living_room_light_on, kitchen_light_on, stereo_on]party_on = MacroCommand(party_on_macro)party_off = MacroCommand([living_room_light_off, kitchen_light_off, stereo_off])remote_control.set_command(3, party_on, party_off)print(remote_control)print()print('---Pushing Macro On---')remote_control.on_button_was_pushed(3)print()print('---Pushing Macro Off---')remote_control.off_button_was_pushed(3)print()print('---Pushing Macro Undo---')remote_control.undo_button_was_pushed()"""运行结果:
[卡槽1]LightOnCommand	LightOffCommand
[卡槽2]LightOnCommand	LightOffCommand
[卡槽3]StereoOnWithCDCommand	StereoOffWithCDCommand
[卡槽4]MacroCommand	MacroCommand
[卡槽5]NoCommand	NoCommand
[卡槽6]NoCommand	NoCommand
[卡槽7]NoCommand	NoCommand---Pushing Macro On---
Living Room light is on.
Kitchen light is on.
Living Room Stereo is on.
Living Room Stereo is set for CD input.
Living Room Stereo volume set to 11.---Pushing Macro Off---
Living Room light is off.
Kitchen light is off.
Living Room Stereo is off.---Pushing Macro Undo---
撤销操作,Living Room light is on.
撤销操作,Kitchen light is on.
撤销操作,Living Room Stereo is on.
"""

命令模式的用途

请求队列、日志请求

总结

在这里插入图片描述

http://www.xdnf.cn/news/12550.html

相关文章:

  • PHP 表单 - 验证邮件和URL
  • Java+Access综合测评系统源码分享:含论文、开题报告、任务书全套资料
  • 物联网智慧医院建设方案(PPT)
  • JMeter-SSE响应数据自动化2.0
  • # STM32F103 SD卡读写程序
  • JDK21深度解密 Day 15:JDK21实战最佳实践总结
  • Go语言堆内存管理
  • 如何在 Java 中优雅地使用 Redisson 实现分布式锁
  • ArcPy扩展模块的使用
  • 深入解析HarmonyOS5 UIAbility组件:从核心架构到实战应用
  • Clickhouse统计指定表中各字段的空值、空字符串或零值比例
  • uniapp- UTS 插件鸿蒙端开发示例 虽然我们这个示例简单 但是这个是难住很多人的一大步
  • 交互标牌——视觉货币(数字)转换器项目及源码
  • 企业微信授权登录(uniapp项目)
  • 零基础在实践中学习网络安全-皮卡丘靶场(第十六期-SSRF模块)
  • 第4章:Cypher查询语言基础
  • GenSpark vs Manus实测对比:文献综述与学术PPT,哪家强?
  • 深度解析:Spring Boot 配置加载顺序、优先级与 bootstrap 上下文
  • 数据通信与计算机网络——数据与信号
  • 好未来0520上机考试题2:有效三角形的个数
  • 青少年编程与数学 01-011 系统软件简介 07 iOS操作系统
  • ClusterRole 和 ClusterRoleBinding 的关系及使用
  • EPPLUS——CAD c#读写EXCEL的第三方库
  • 怎么让自己ip显示外省?一文说清操作
  • moon游戏服务器-demo运行
  • Lodash原型污染漏洞原理详解
  • [HCTF 2018]admin 1
  • N元语言模型 —— 一文讲懂!!!
  • 设计模式-观察着模式
  • 关于脏读,幻读,可重复读的学习