python-命令模式
源码地址:https://github.com/weilanhanf/PythonDesignPatterns
说明:
命令在发送方被激活,而在接收方被响应。一个对象既可以作为命令的发送方,也可以作为命令的接收方,或者都可以。命令的典型应用就是图形用户界面开发。每一个窗体都包含菜单,工具栏,按钮等控件,将用户的单机动作也叫命令作为外部事件,然后系统会根据绑定的事件处理程序执行相应的动作即命令获得响应,完成用户发出的请求。
大多数情况下,命令的调用者和接收者是前期绑定的,但是想要对命令进行操作的时候,就需要撤销命令的调用者和接收者之间的紧密耦合关系,使得二者相互独立。
命令模式(Command Pattern):将请求封装成对象,将其作为命令调用者和接收者的中介,而抽象出来的命令对象又使得能够对一系列请求进行特殊操作,比如:对请求排队或记录请求日志,以及支持可撤消的操作.

结构组成:
命令角色,具体命令角色,接收者角色,请求者(调用者)角色(Invoker),客户角色(Client)
实例:
在大多数饭店中,当服务员已经接到顾客的点单,录入到系统中后,根据不同的菜品,会有不同的后台反应。比如,饭店有凉菜间、热菜间、主食间,那当服务员将菜品录入到系统中后,凉菜间会打印出顾客所点的凉菜条目,热菜间会打印出顾客所点的热菜条目,主食间会打印出主食条目。那这个系统的后台模式该如何设计?当然,直接在场景代码中加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:Notify...")
for command in self.commandList:
command.execute() #前台系统中的notify接口直接调用命令中的execute接口,执行命令。命令类构建
class Command():
receiver = None
def __init__(self, receiver):
self.receiver = receiver
def execute(self):
pass
class foodCommand(Command):
dish=""
def __init__(self,receiver,dish):
self.receiver=receiver
self.dish=dish
def 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接口。
这样,后台三个命令类就可以直接继承,不用进行修改了。
""" #菜单类辅助业务
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 True
return False
def isCool(self,dish):
if dish in self.menu_map["cool"]:
return True
return False
def isMain(self,dish):
if dish in self.menu_map["main"]:
return True
return 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:
continue
waiter_sys.setOrder(cmd)
waiter_sys.notify()
打印结果:
WAITER:Add dish
WAITER:Add dish
WAITER:Add dish
WAITER:Add dish
WAITER:Notify...
HOTDISH:Cook Yu-Shiang Shredded Pork
HOTDISH:Cook Sauteed Tofu, Home Style
COOLDISH:Cook Cucumber
MAINFOOD:Cook Rice
优点:
缺点:
适用性:
系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互。
在不同的时刻指定、排列和执行请求。
支持修改日志、撤销操作。
系统需要将一组操作组合在一起,即支持宏命令。
python-命令模式的更多相关文章
- Python 命令模式和交互模式
命令模式 在系统CMD命名模式下执行 命令执行到脚本所在目录 执行python Test.py 可直接一次执行完脚本里面所有的语句 交互模式下 一行一行执行
- 区分命令行模式和Python交互模式
命令行模式 在Windows开始菜单选择"命令提示符",就进入到命令行模式,它的提示符类似C:\> Python交互模式 在命令行模式下敲命令python,就看到类似如下的一 ...
- 命令行以及Python交互模式下python程序的编写
一.命令行模式 在Windows开始菜单选择“命令提示符”,就进入到命令行模式,它的提示符类似C:\>: 二.Python交互模式 在命令行模式下敲命令python,就看到类似如下的一堆文本输出 ...
- Python的命令模式和交互模式
Python的命令行模式和交互模式 请注意区分命令行模式和Python交互模式. 在命令行模式下,可以执行python进入Python交互式环境,也可以执行python first.py运行一个.py ...
- 命令行模式和python交互模式
一.命令行模式 在Windows开始菜单选择“命令提示符”,就进入到命令行模式,它的提示符类似C:>:. 二.Python交互模式 在命令行模式下敲命令python,就看到类似如下的一堆文本输出 ...
- 大话设计模式Python实现-命令模式
命令模式(Command Pattern):将请求封装成对象,从而使可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可撤消的操作. 下面是一个命令模式的demo: #!/usr/bi ...
- python设计模式-命令模式
命令模式就是对命令的封装.所谓封装命令,就是将一系列操作封装到命令类中,并且命令类只需要对外公开一个执行方法execute,调用此命令的对象只需要执行命令的execute方法就可以完成所有的操作.这样 ...
- 命令行模式和Python交互模式的区别
1.命令行模式: 在Windows开始菜单选择“命令提示符”,就进入到命令行模式,它的提示符类似C:\Users\>: 2.python交互模式 在命令行模式下敲命令python,就看到类似如下 ...
- python设计模式之命令模式
python设计模式之命令模式 现在多数应用都有撤销操作.虽然难以想象,但在很多年里,任何软件中确实都不存在撤销操作.撤销操作是在1974年引入的,但Fortran和Lisp分别早在1957年和195 ...
- python学习第二天:命令行模式和python交互模式
命令行模式 安装完python开发环境和工具之后,在Windows开始菜单选择"命令提示符",就会进入到命令行模式: 或者都可以,然后 点击enter键,弹出下图中的窗口,即命令行 ...
随机推荐
- 题解 P2146 【[NOI2015]软件包管理器】
题目大意 给你一棵树, 求一点到根的路径上有多少个未标记点并全标记, 和询问一个点的子树内有多少已标记点和撤销标记 解题方法 1: install 操作 这个操作是求一点到根的路径上有多少个未 ...
- df换行问题解决
df换行问题解决 df是linux下用来查磁盘空间的命令,而在使用了LVM分区或网络挂载的情况下,再用df取分区的使用率时,发现有些分区显示换行了,这样会导致通过脚本取的数据不对. [root@ ]# ...
- 【disruptor】1、关于disruptor中的SequenceBarrier对象
首先这个类的uml结构在disruptor中是这样的,里面只有部分的属性对象和函数内容,具体有什么作用,用到了再说,用不到我也不会... 1.那么这个对象有什么用呢? 注意我们这个类中有哪些属性: 我 ...
- DWZ中刷新dialog的方案解决
在DWZ中进行ajax表单提交后,通过回调函数来返回状态结果,以及返回是否需要刷新父页的navTabId. DWZ给我们提供了两个回调函数,一个是子窗口为navTab的navTabAjaxDone,一 ...
- Redis学习系列六ZSet(有序列表)及Redis数据结构的过期
一.简介 ZSet可以说是Redis中最有趣的数据结构了,因为他兼具了Hash集合和Set的双重特性,也是用的最多的,保证了value值的唯一性的同时,,同时又保证了高性能,最主要的是还可以给每个Va ...
- 把 Elasticsearch 当数据库使:聚合后排序
使用 https://github.com/taowen/es-monitor 可以用 SQL 进行 elasticsearch 的查询.有的时候分桶聚合之后会产生很多的桶,我们只对其中部分的桶关心. ...
- Elasticsearch聚合 Date Histogram聚合
转 http://www.cnblogs.com/xing901022/p/4951603.html Elasticsearch的聚合主要分成两大类:metric和bucket,2.0中新增了pipe ...
- SQL Server性能优化(7)理解数据库文件组织
一.基本单位"页" SQL Server是用8KB的页来存储数据.物理I/O操作也是在页级执行.页的种类有很多,具体参考(MSDN).我们关注更多的是数据页的结构,包括三部 ...
- Elasticsearch 5.X 使用 Docker 运行使用 Head 插件
ES 5.X 版本后就不支持 elasticsearch-head 以插件方式来安装了. for Elasticsearch 5.x: site plugins are not supported. ...
- 15 图-图的遍历-基于邻接矩阵实现的BFS与DFS算法
算法分析和具体步骤解说直接写在代码注释上了 TvT 没时间了等下还要去洗衣服 就先不赘述了 有不明白的欢迎留言交流!(估计是没人看的了) 直接上代码: #include<stdio.h> ...