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的需求。 二、需要学什么…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?
Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...
DingDing机器人群消息推送
文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人,点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置,详见说明文档 成功后,记录Webhook 2 API文档说明 点击设置说明 查看自…...
