Python与设计模式--命令模式
23种计模式之 前言 +(5)单例模式、工厂模式、简单工厂模式、抽象工厂模式、建造者模式、原型模式、+(7)代理模式、装饰器模式、适配器模式、门面模式、组合模式、享元模式、桥梁模式、+(11)策略模式、责任链模式、命令模式、中介者模式、模板模式、迭代器模式、访问者模式、观察者模式、解释器模式、备忘录模式、状态模式 + 设计原则
14-Python与设计模式–命令模式
一、饭店点餐系统
又是一个点餐系统(原谅作者的吃货属性)。不过这次的点餐系统是个饭店的点餐系统。
饭店的点餐系统有什么不同嘛?大伙想想看,在大多数饭店中,当服务员已经接到顾客的点单,
录入到系统中后,根据不同的菜品,会有不同的后台反应。比如,饭店有凉菜间、热菜间、主食间,
那当服务员将菜品录入到系统中后,凉菜间会打印出顾客所点的凉菜条目,热菜间会打印出顾客
所点的热菜条目,主食间会打印出主食条目。那这个系统的后台模式该如何设计?当然,
直接在场景代码中加if…else…语句判断是个方法,可这样做又一次加重了系统耦合,违反了单一职责原则,
遇到系统需求变动时,又会轻易违反开闭原则。所以,我们需要重新组织一下结构。
可以将该系统设计成前台服务员系统和后台系统,后台系统进一步细分成主食子系统,凉菜子系统,热菜子系统。
后台三个子系统设计如下:
class backSys():def cook(self,dish):pass
class mainFoodSys(backSys):def cook(self,dish):print "MAINFOOD:Cook %s"%dish
class coolDishSys(backSys):def cook(self,dish):print "COOLDISH:Cook %s"%dish
class hotDishSys(backSys):def cook(self,dish):print "HOTDISH:Cook %s"%dish
前台服务员系统与后台系统的交互,我们可以通过命令的模式来实现,服务员将顾客的点单内容封装成命令,直接对后台下达命令,后台完成命令要求的事,即可。
前台系统构建如下:
class waiterSys():menu_map=dict()commandList=[]def setOrder(self,command):print "WAITER:Add dish"self.commandList.append(command)def cancelOrder(self,command):print "WAITER:Cancel order..."self.commandList.remove(command)def notify(self):print "WAITER:Nofify..."for command in self.commandList:command.execute()
前台系统中的notify接口直接调用命令中的execute接口,执行命令。
命令类构建如下:
class Command():receiver = Nonedef __init__(self, receiver):self.receiver = receiverdef execute(self):pass
class foodCommand(Command):dish=""def __init__(self,receiver,dish):self.receiver=receiverself.dish=dishdef execute(self):self.receiver.cook(self.dish)class mainFoodCommand(foodCommand):pass
class coolDishCommand(foodCommand):pass
class hotDishCommand(foodCommand):pass
Command类是个比较通过的类,foodCommand类是本例中涉及的类,相比于Command类进行了一定的改造。
由于后台系统中的执行函数都是cook,因而在foodCommand类中直接将execute接口实现,如果后台系统执行
函数不同,需要在三个子命令系统中实现execute接口。这样,后台三个命令类就可以直接继承,
不用进行修改了。(这里子系统没有变动,可以将三个子系统的命令废弃不用,直接用foodCommand吗?
当然可以,各有利蔽。请读者结合自身开发经验,进行思考相对于自己业务场景的使用,哪种方式更好。)
为使场景业务精简一些,我们再加一个菜单类来辅助业务,菜单类在本例中直接写死。
class menuAll:menu_map=dict()def loadMenu(self):#加载菜单,这里直接写死self.menu_map["hot"] = ["Yu-Shiang Shredded Pork", "Sauteed Tofu, Home Style", "Sauteed Snow Peas"]self.menu_map["cool"] = ["Cucumber", "Preserved egg"]self.menu_map["main"] = ["Rice", "Pie"]def isHot(self,dish):if dish in self.menu_map["hot"]:return Truereturn Falsedef isCool(self,dish):if dish in self.menu_map["cool"]:return Truereturn Falsedef isMain(self,dish):if dish in self.menu_map["main"]:return Truereturn False
业务场景如下:
if __name__=="__main__":dish_list=["Yu-Shiang Shredded Pork","Sauteed Tofu, Home Style","Cucumber","Rice"]#顾客点的菜waiter_sys=waiterSys()main_food_sys=mainFoodSys()cool_dish_sys=coolDishSys()hot_dish_sys=hotDishSys()menu=menuAll()menu.loadMenu()for dish in dish_list:if menu.isCool(dish):cmd=coolDishCommand(cool_dish_sys,dish)elif menu.isHot(dish):cmd=hotDishCommand(hot_dish_sys,dish)elif menu.isMain(dish):cmd=mainFoodCommand(main_food_sys,dish)else:continuewaiter_sys.setOrder(cmd)waiter_sys.notify()
打印如下:
WAITER:Add dish WAITER:Add dish WAITER:Add dish WAITER:Add dish
WAITER:Nofify… HOTDISH:Cook Yu-Shiang Shredded Pork HOTDISH:Cook
Sauteed Tofu, Home Style COOLDISH:Cook Cucumber MAINFOOD:Cook Rice
二、命令模式
命令模式的定义为:将一个请求封装成一个对象,从而可以使用不同的请求将客户端参数化,对请求排队或者
记录请求日志,可以提供命令的撤销和恢复功能。命令模式中通常涉及三类对象的抽象:Receiver,Command,
Invoker(本例中的waiterSys)。
只有一个Invoker的命令模式也可以抽象成一个类似的“星形网络”,但与之前介绍的中介者模式不同,
单纯的命令模式更像是一个辐射状的结构,由Invoker直接对Receiver传递命令,而一般不反向传递,
中介者模式“星形网络”的中心,是个协调者,抽象结节间的信息流全部或者部分是双向的。
另外,命令模式的定义中提到了“撤销和恢复功能”,也给了各位开发人员一个命令模式使用过程中的建议:
各个Receiver中可以设计一个回滚接口,支持命令的“撤销”。
三、命令模式的优点和应用场景
优点:
1、低耦合:调用者和接收者之间没有什么直接关系,二者通过命令中的execute接口联系;
2、扩展性好:新命令很容易加入,也很容易拼出“组合命令”。应用场景:
1、触发-反馈机制的系统,都可以使用命令模式思想。如基于管道结构的命令系统(如SHELL),可以直接套用命令模式;此外,GUI系统中的操作反馈(如点击、键入等),也可以使用命令模式思想。
四、命令模式的缺点
1、如果业务场景中命令比较多,那么对应命令类和命令对象的数量也会增加,这样系统会膨胀得很大。
相关文章:
Python与设计模式--命令模式
23种计模式之 前言 (5)单例模式、工厂模式、简单工厂模式、抽象工厂模式、建造者模式、原型模式、(7)代理模式、装饰器模式、适配器模式、门面模式、组合模式、享元模式、桥梁模式、(11)策略模式、责任链模式、命令模式、中介者模…...
uni-app 自带返回方法onBackPress,返回上一级并且刷新页面内容获取最新的数据
onBackPress 返回上一级并且刷新页面内容获取最新的数据 onBackPress 方法是uinapp自带返回键方法,也就是在app和H5返回键 onBackPress() {setTimeout(() > {uni.switchTab({url: /pages/Users/index,})}, 300)return true}, methods: {}在这里 uni.switchTab…...
python用YOLOv8对图片进行分类
用yolov8的模型进行分类 先上效果图 图片资源 模型下载地址 https://github.com/ultralytics/ultralytics 代码 import matplotlib.pyplot as plt from ultralytics import YOLO from PIL import Image import cv2model YOLO(../ultralytics/yolov8n.pt)# print(model…...
Spring中@DependsOn 使用详解
一、注解源码 Target({ElementType.TYPE, ElementType.METHOD}) Retention(RetentionPolicy.RUNTIME) Documented public interface DependsOn {String[] value() default {}; } 二、基础概念 DependsOn是Spring框架用来指定bean之间依赖关系的注解之一,即可用户类…...
android笔记 SELinux
1.SELinux解错步骤 log信息: 11-20 02:25:12.526 8976 8976 W om.jzzh.setting: type1400 audit(0.0:1316): avc: denied { write } for name"com.jzzh.setting-IWLR9dkz8TWizbNujdTpWw" dev"mmcblk2p15" ino2661 scontextu:r:system_app:s0…...
vue3 keep-alive页面切换报错:parentComponent.ctx.deactivate is not a function
问题: <router-view v-slot"{ Component }"><keep-alive ><component :is"Component" v-if"$route.meta.keepAlive" /></keep-alive><component :is"Component" v-if"!$route.meta.keepA…...
prompt提示
用例生成 # 任务描述 作为一个高级c程序员,需要完成下列功能的gtest测试用例 # 功能描述 给定两个数字型字符串s1和s2,求和,返回值也是字符串 # 接口举例 调用strAdd("123", "132"),输出“255” # 输出要求 - 入参为空串、nu…...
边缘计算网关:智能制造的“智慧大脑”
一、智能制造的崛起 随着科技的飞速发展,智能制造已经成为了制造业的新趋势。智能制造不仅能够提高生产效率,降低生产成本,还能够实现个性化定制,满足消费者多样化的需求。然而,智能制造的实现离不开大量的数据处理和分…...
HNCTF2022Week1 Reverse WP
文章目录 [HNCTF 2022 Week1]超级签到[HNCTF 2022 Week1]贝斯是什么乐器啊?[HNCTF 2022 Week1]X0r[HNCTF 2022 Week1]你知道什么是Py嘛?[HNCTF 2022 Week1]CrackMe[HNCTF 2022 Week1]给阿姨倒一杯Jvav[HNCTF 2022 Week1]Little EndianNSSCTF{Littl3_Endi…...
基于Python的面向对象分类实例Ⅱ
接上一部分继续介绍~ 一、地类矢量转栅格 这一步是为了能让地类值和影像的对象落在同一区域,从而将影像中的分割对象同化为实际地物类别。 train_fn r".\train_data1.shp" train_ds ogr.Open(train_fn) lyr train_ds.GetLayer() driver gdal.GetDrive…...
android手机莫名其妙卸载重装有残留数据
参考文档: https://developer.android.com/guide/topics/data/autobackup?hlzh-cn https://developer.android.com/about/versions/12/backup-restore#xml-changes https://stackoverflow.com/questions/70365809/how-to-specify-to-not-allow-any-data-backup-wit…...
【YOLOv5入门】目标检测
【大家好,我是爱干饭的猿,本文重点介绍YOLOv5入门-目标检测的任务、性能指标、yolo算法基本思想、yolov5网络架构图。 后续会继续分享其他重要知识点总结,如果喜欢这篇文章,点个赞👍,关注一下吧】 上一篇…...
可验证随机函数(VRF)
文章目录 一、背景以及场景共识发展第一代 POW “以力取胜”第二代 POS/DPOS “民主投票”第三代 VRF “运气抽签” 二、可验证随机函数(VRF)快速开始1. VRF是什么?2. MD5 hash函数和VRF(Verifiable Random Function)区别3. VRF-…...
Node.js与npm的准备与操作
1.下载 Node.js官网:Node.jsNode.js is a JavaScript runtime built on Chromes V8 JavaScript engine.https://nodejs.org/en 打开后的界面如下: LTS(Long Term Support):长期支持版,稳定版 Current&am…...
ui设计师简历自我评价的范文(合集)
ui设计师简历自我评价的范文篇一 本人毕业于艺术设计专业,具有较高的艺术素养,平时注重设计理论知识的积累,并将理论应用到作品中。了解当下设计的流行趋势,设计注重细节、重视用户体验,对色彩搭配有着浓厚的兴趣&…...
sqli-labs靶场详解(less32-less37)
宽字节注入 原理在下方 目录 less-32 less-33 less-34 less-35 less-36 less-37 less-32 正常页面 ?id1 下面有提示 获取到了Hint: The Query String you input is escaped as : 1\ ?id1 看来是把参数中的非法字符就加上了转义 从而在数据库中只能把单引号当成普通的字…...
如何保证缓存和数据库的双写一致性?
一、什么是数据库和缓存双写一致性? 在分布式系统中,数据库和缓存会搭配一起使用,以此来保证程序的整体查询性能。也就说,分布式系统为了缓解数据库查询的压力,会将查出来的数据保存在缓存中,下次再查询时…...
Rosbag 制作 TUM数据集
Rosbag 制作 TUM数据集 一、创建rgb和depth文件夹和txt文件 mkdir rgb mkdir depth touch rgb.txt touch depth.txt 二、替换 bag 路径 和 topic tum.py: import os import cv2 import numpy as np import rosbag from sensor_msgs.msg import Image from cv_b…...
本地websocket服务端暴露至公网访问【cpolar内网穿透】
本地websocket服务端暴露至公网访问【cpolar内网穿透】 文章目录 本地websocket服务端暴露至公网访问【cpolar内网穿透】1. Java 服务端demo环境2. 在pom文件引入第三包封装的netty框架maven坐标3. 创建服务端,以接口模式调用,方便外部调用4. 启动服务,出现以下信息表示启动成功…...
男UI设计师主要是做什么的优漫教育
1、根据各种相关软件的用户群,提出构思新颖、有高度吸引力的创意设计; 2、对页面进行优化,使用户操作更趋于人性化; 3、维护现有的应用产品; 4、收集和分析用户对于GUI的需求。 二、需要学什么…...
Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...
排序算法总结(C++)
目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...
Spring Security 认证流程——补充
一、认证流程概述 Spring Security 的认证流程基于 过滤器链(Filter Chain),核心组件包括 UsernamePasswordAuthenticationFilter、AuthenticationManager、UserDetailsService 等。整个流程可分为以下步骤: 用户提交登录请求拦…...
沙箱虚拟化技术虚拟机容器之间的关系详解
问题 沙箱、虚拟化、容器三者分开一一介绍的话我知道他们各自都是什么东西,但是如果把三者放在一起,它们之间到底什么关系?又有什么联系呢?我不是很明白!!! 就比如说: 沙箱&#…...
鸿蒙(HarmonyOS5)实现跳一跳小游戏
下面我将介绍如何使用鸿蒙的ArkUI框架,实现一个简单的跳一跳小游戏。 1. 项目结构 src/main/ets/ ├── MainAbility │ ├── pages │ │ ├── Index.ets // 主页面 │ │ └── GamePage.ets // 游戏页面 │ └── model │ …...
