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键,弹出下图中的窗口,即命令行 ...
随机推荐
- tcp server
SO_REUSEADDR Ignore SIGPIPE TCP_NODELAY TCP_QUICKACK
- ST表的原理及其实现
ST表类似树状数组,线段树这两种算法,是一种用于解决RMQ(Range Minimum/Maximum Query,即区间最值查询)问题的离线算法 与线段树相比,预处理复杂度同为O(nlogn),查询 ...
- Oracle SQL Developer连接报错以及链接oracle的sqlplus出现协议适配器错误
之前用的好好的Oracle SQL Developer,不知道是不是匆忙关闭软件啥东西没保存或是删了什么东西,今天突然用不了的. 大清早的,打开Oracle SQL Developer,就给我一个惊喜 ...
- Python程序的打包-上传到pypi
pypi注册与配置 在pypi的官网:https://pypi.python.org/pypi 注册自己的账号激活账号之后,我们还需要将在本地配置一份文件 在用户的根目录创建文件 : .pypirc在 ...
- mysql之视图,存储过程,触发器,事务
视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,可以将该结果集当做表来使用. 使用视图我们可以把查询过程中的临时 ...
- POJ 2453
#include <iostream> #include <algorithm> #include <cmath> #define MAXN 1000 #defin ...
- Dell R730服务器 Raid5配置
Dell R730服务器,有7块5t硬盘,默认做的RAID5.我们的目的是取其中6块硬盘做RAID5,留一块硬盘做热备. 一块SSD系统盘. 在这里,我具体解释一下 ①6块硬盘做成RAID5 ②6块硬 ...
- asp.net core 系列之用户认证(1)-给项目添加 Identity
对于没有包含认证(authentication),的项目,你可以使用基架(scaffolder)把 Identity的程序集包加入到项目中,并且选择性的添加Identity的代码进行生成. 虽然基架已 ...
- nginx lua集成
版本说明: linux: 1.8.1 luajit:2.0.2(不要使用标准lua,应当使用luajit, 后者的效率比前者高很多) ngx_devel_kit: 0.2.18 lua-nginx-m ...
- 解决docker镜像无法下载的问题
从daocloud.io中找到了获取镜像的方式,在镜像仓库中可以找到镜像的地址,其他镜像地址可以以此类推: # docker pull daocloud.io/library/centos:lates ...