源码地址: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-命令模式的更多相关文章

  1. Python 命令模式和交互模式

    命令模式 在系统CMD命名模式下执行 命令执行到脚本所在目录 执行python Test.py 可直接一次执行完脚本里面所有的语句 交互模式下 一行一行执行

  2. 区分命令行模式和Python交互模式

    命令行模式 在Windows开始菜单选择"命令提示符",就进入到命令行模式,它的提示符类似C:\> Python交互模式 在命令行模式下敲命令python,就看到类似如下的一 ...

  3. 命令行以及Python交互模式下python程序的编写

    一.命令行模式 在Windows开始菜单选择“命令提示符”,就进入到命令行模式,它的提示符类似C:\>: 二.Python交互模式 在命令行模式下敲命令python,就看到类似如下的一堆文本输出 ...

  4. Python的命令模式和交互模式

    Python的命令行模式和交互模式 请注意区分命令行模式和Python交互模式. 在命令行模式下,可以执行python进入Python交互式环境,也可以执行python first.py运行一个.py ...

  5. 命令行模式和python交互模式

    一.命令行模式 在Windows开始菜单选择“命令提示符”,就进入到命令行模式,它的提示符类似C:>:. 二.Python交互模式 在命令行模式下敲命令python,就看到类似如下的一堆文本输出 ...

  6. 大话设计模式Python实现-命令模式

    命令模式(Command Pattern):将请求封装成对象,从而使可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可撤消的操作. 下面是一个命令模式的demo: #!/usr/bi ...

  7. python设计模式-命令模式

    命令模式就是对命令的封装.所谓封装命令,就是将一系列操作封装到命令类中,并且命令类只需要对外公开一个执行方法execute,调用此命令的对象只需要执行命令的execute方法就可以完成所有的操作.这样 ...

  8. 命令行模式和Python交互模式的区别

    1.命令行模式: 在Windows开始菜单选择“命令提示符”,就进入到命令行模式,它的提示符类似C:\Users\>: 2.python交互模式 在命令行模式下敲命令python,就看到类似如下 ...

  9. python设计模式之命令模式

    python设计模式之命令模式 现在多数应用都有撤销操作.虽然难以想象,但在很多年里,任何软件中确实都不存在撤销操作.撤销操作是在1974年引入的,但Fortran和Lisp分别早在1957年和195 ...

  10. python学习第二天:命令行模式和python交互模式

    命令行模式 安装完python开发环境和工具之后,在Windows开始菜单选择"命令提示符",就会进入到命令行模式: 或者都可以,然后 点击enter键,弹出下图中的窗口,即命令行 ...

随机推荐

  1. [vuejs] 深入响应式原理

    深入响应式原理 现在是时候深入一下了!Vue 最独特的特性之一,是其非侵入性的响应式系统.数据模型仅仅是普通的 JavaScript 对象.而当你修改它们时,视图会进行更新.这使得状态管理非常简单直接 ...

  2. 【5】JMicro微服务-熔断降级

    如非授权,禁止用于商业用途,转载请注明出处作者:mynewworldyyl   1. 使用服务熔断降级特性,必须先启动Pubsub服务,服务监听服务,熔断器服务3个服务 先启动Pubsub及服务监听两 ...

  3. flask加vue 动画 加载更多

    曾经使用flask_paginate(地址:https://blog.csdn.net/qq_42239520/article/details/80378095)进行分页,现在又想新的想法,怎么才能和 ...

  4. Mac 下配置 Python 开发环境

    ➜ ~ sudo brew install python3 ==> Downloading https://www.python.org/ftp/python/3.5.1/Python-3.5. ...

  5. Json.Net 在.Net Core 2.0 中序列化DataSet 问题

    使用Asp.Net Core中自带的版本10.0.1 生成一个简单的DataSet DataSet ds2 = new DataSet(); DataTable table = new DataTab ...

  6. 分享一套简单的CodeSmith三层模板

    如果要连接mysql,需要安装驱动: https://cdn.mysql.com//Downloads/Connector-Net/mysql-connector-net-8.0.12.msi 连接字 ...

  7. Android中实现activity的页面跳转并传值

    一个Android应用程序很少会只有一个Activity对象,如何在多个Activity之间进行跳转,而且能够互相传值是一个很基本的要求. 本次我们就讲一下,Android中页面跳转以及传值的几种方式 ...

  8. Android返回系统Home桌面

    Intent intent = new Intent(); // 为Intent设置Action.Category属性 intent.setAction(Intent.ACTION_MAIN);// ...

  9. docker-部署elk-6.1.3

    1.更新daocker版本 2.pull官方的镜像 https://www.elastic.co/guide/en/elasticsearch/reference/6.1/docker.html ht ...

  10. java Multimap

    实现 { "a": [ , , ], "b": [ , ] } 当然, HashMap<String, List<Integer>> 是 ...