命令模式就是对命令的封装。所谓封装命令,就是将一系列操作封装到命令类中,并且命令类只需要对外公开一个执行方法execute,调用此命令的对象只需要执行命令的execute方法就可以完成所有的操作。这样调用此命令的对象就和命令具体操作之间解耦了。更进一步,通过命令模式我们可以抽象出调用者,接收者和命令三个对象。调用者就是简单的调用命令,然后将命令发送给接收者,而接收者则接收并执行命令,执行命令的方式也是简单的调用命令的execute方法就可以了。发送者与接收者之间没有直接引用关系,发送请求的对象只需要知道如何发送请求,而不必知道如何完成请求。下面让我们使用 Python 来实现命令模式。

# -*- coding: utf-8 -*-

import abc

class VmReceiver(object):
"""
命令接收者,真正执行命令的地方
""" def start(self):
print("虚拟机开始") def stop(self):
print("虚拟机停止") class Command(object):
"""
命令抽象类
"""
__metaclass__ = abc.ABCMeta @abc.abstractmethod
def execute(self):
"""
命令对象对外只提供 execute 方法
"""
pass class StartVmCommand(Command):
"""
开启虚拟机的命令
""" def __init__(self, recevier):
"""
使用一个命令接收者初始化
"""
self.recevier = recevier def execute(self):
"""
真正执行命令的时候命令接收者开启虚拟机
"""
self.recevier.start() class StopVmCommand(Command):
"""
停止虚拟机的命令
""" def __init__(self, recevier):
"""
使用一个命令接收者初始化
"""
self.recevier = recevier def execute(self):
"""
真正执行命令的时候命令接收者关闭虚拟机
"""
self.recevier.stop() class ClientInvoker(object):
"""
命令调用者
""" def __init__(self, command):
self.command = command def do(self):
self.command.execute() if __name__ == '__main__':
recevier = VmReceiver()
start_command = StartVmCommand(recevier)
# 命令调用者同时也是客户端,通过命令实例也执行真正的操作
client = ClientInvoker(start_command)
client.do() # 能告诉命令接收者执行不同的操作
stop_command = StopVmCommand(recevier)
client.command = stop_command
client.do()

运行:

E:\实验楼学习\venv\Scripts\python.exe E:/实验楼学习/设计模式/command/command-1.py
虚拟机开始
虚拟机停止 Process finished with exit code 0

以上代码中,通过启动和停止 Linux 虚拟机的例子实现了命令模式。通过命令模式,使命令调用者ClinetInvoker和命令接收者VmRecevier之间解耦,前者不必知道后者具体是怎么操作虚拟机的,只需要通过ClientInvoker.do()方法调用Command.execute()方法能完成虚拟机的相关操作。

总的来说,命令模式的封装性很好:每个命令都被封装起来,对于客户端来说,需要什么功能就去调用相应的命令,而无需知道命令具体是怎么执行的。同时命令模式的扩展性很好,在命令模式中,在接收者类中一般会对操作进行最基本的封装,命令类则通过对这些基本的操作进行二次封装,当增加新命令的时候,对命令类的编写一般不是从零开始的,有大量的接收者类可供调用,也有大量的命令类可供调用,代码的复用性很好。

python设计模式-命令模式的更多相关文章

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

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

  2. linkin大话设计模式--命令模式

    linkin大话设计模式--命令模式 首先考虑一种应用情况,某个方法需要完成某一个功能,这个功能的大部分功能已经确定了,但是有可能少量的步骤没法确定,必须等到执行这个方法才可以确定. 也就是说,我们写 ...

  3. 浅谈Python设计模式 - 外观模式

    声明:本系列文章主要参考<精通Python设计模式>一书,并且参考一些资料,结合自己的一些看法来总结而来. 外观模式 外观模式的核心在于将复杂的内部实现包装起来,只向外界提供简单的调用接口 ...

  4. 【设计模式】Java设计模式 - 命令模式

    Java设计模式 - 命令模式 生命不息,写作不止 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长! 目录 Ja ...

  5. 浅谈Python设计模式 - 工厂模式

    声明:本系列文章主要参考<精通Python设计模式>一书,并且参考一些资料,结合自己的一些看法来总结而来. 工厂模式: 顾名思义,工厂则是根据提供的不同的材料,生产出不同的产品.那么在编程 ...

  6. [Head First设计模式]餐馆中的设计模式——命令模式

    系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...

  7. JAVA 设计模式 命令模式

    用途 命令模式 (Command) 将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化:对请求排队或请求日志,以及支持可撤销的操作. 命令模式是一种行为型模式. 结构

  8. 深入浅出设计模式——命令模式(Command Pattern)

    模式动机 在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计,使得请 ...

  9. Java设计模式-命令模式(Command)

    命令模式很好理解,举个例子,司令员下令让士兵去干件事情,从整个事情的角度来考虑,司令员的作用是,发出口令,口令经过传递,传到了士兵耳朵里,士兵去执行.这个过程好在,三者相互解耦,任何一方都不用去依赖其 ...

随机推荐

  1. OverflowError:django signed integer is greater than maximum 数据库日期字段相关错

    使用django中的默认数据库sqlite3, 在pycharm中录入日期字段相关信息结果出现问题 在保存的时候如图 直接在界面选择的日期变成了时间戳, 并且在获取数据的时候报错 经过查询之后(舔大佬 ...

  2. linux基础5-vi文本处理器

    三种模式下各自可以完成的操作: 一般模式:可以完成光标移动.删除单个和整行字.复制和黏贴,通过i.o.a.r这几个命令进入编辑模式 编辑模式:可以输入字符,通过esc返回一般模式 指令模式:读取文件, ...

  3. K8S搭建过程随笔_系统初始化

    组件 Kubernetes 1.14.2 Docker 18.09.6-ce Etcd 3.3.13 Flanneld 0.11.0 基础环境设置 192.168.11.188 k8s-master ...

  4. SQL使用 dateadd添加使天数加x

    ,Receivedate)), ) --第一个参数 表示增加什么(day ) --第二个参数表示增加多少( int ) --第三个参数表示那个字段  (Receivedate 字段属性) conver ...

  5. 构建官方example

    开发工具的选择: 构建官方example:

  6. vue.js中父组件触发子组件中的方法

    知识点:vue.js中,父组件的method中,触发子组件中的方法,获得子组件中的定义的属性 (1)子组件 : child_crud.js var html_child_crud= "< ...

  7. Error resolving template “pages”, template might not exist or might not be accessible by any of the configured Template Resolver 或者 springboot使用thymeleaf时报html没有结束标签

    application.properties配置文件 spring.thymeleaf.prefix=classpath:/templates/ spring.thymeleaf.suffix=.ht ...

  8. golang打包和部署到centos7

    一.环境说明:VS code 二.编译: set GOOS=linux set GOARCH=amd64 go build -o "packageName"   三.发布 上传到服 ...

  9. spark_rdd 一波怼完面试官系列

    Resilient Distributed dataset , 弹性分布式数据集. 分布式内存的抽象使用,实现了以操作本地集合的方式来操作分布式数据集的抽象实现. RDD是Spark最核心的东西,它表 ...

  10. bzoj1497: [NOI2006]最大获利(最小割)

    传送门 第一眼看去:好难 第二眼:不就是个裸的最大权闭合子图么…… 我们从源点向所有用户连边,容量为收益,用户向自己的中转站连边,容量为INF,中转站向汇点连边,容量为费用 那么总收益-最小割就是答案 ...