命令模式就是对命令的封装。所谓封装命令,就是将一系列操作封装到命令类中,并且命令类只需要对外公开一个执行方法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()方法能完成虚拟机的相关操作。

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

最新文章

  1. redux学习
  2. 第二天--html+css
  3. LookUpEditPopup自动调整宽度
  4. xml ---DOM操作
  5. c++虚函数注意事项
  6. .Net SqlDbHelper
  7. XPath 语法示例
  8. Nginx高性能服务器安装、配置、运维 (4) —— Nginx服务、架构及其信号
  9. XML和对象属性互转的基类
  10. Android UI 笔记
  11. Uva 11400 照明系统
  12. Java-IO之管道(PipedInputStream和PipedOutputStream)
  13. Activiti6事件及监听器配置(学习笔记)
  14. c/c++面试题一
  15. [matlab] 12.Optimization Tool的使用
  16. 关键字搜索:jQuery过滤器插件fastLiveFilter||显示结果条数
  17. 洛谷 P4151 [WC2011]最大XOR和路径 解题报告
  18. MHA-Failover可能遇到的坑
  19. MySQL免安装配置(亲测过,请放心借鉴)
  20. HTTP是用来做什么的

热门文章

  1. Django学习:创建admin后台管理站点
  2. (二十四)Ubuntu16.04配置ADB调试环境
  3. C# Winform 禁止一个进程运行多次
  4. 十:Razor语法
  5. TcxComboBoxProperties下拉框填充
  6. pip安装tesserocr时报错
  7. P2402 奶牛隐藏 二分+网络流
  8. hg如何回退到某个版本
  9. bat 获取当前文件夹的文件名
  10. ssh推送安装mysql脚本