设计模式:命令模式
时间:2022-04-25
本文章向大家介绍设计模式:命令模式,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
今天说一下命令模式
命令模式 将请求封装成对象,以便使用不同的请求、队列或者日志来参数化其它对象。命令模式也支持可撤销的操作。这样将“行为请求者”与“行为实现者”解耦, 实现松耦合
我们来看一个类图
电视机遥控器就是一个典型的命令模式应用实例: 电视机是请求的接收者,遥控器是请求的发送者,遥控器上有一些按钮,不同的按钮对应电视机的不同操作。 抽象命令角色由一个命令接口来扮演,有三个具体的命令类实现了一个抽象命令接口,这三个具体命令类分别代表三个操作:打开电视、 关闭电视、和切换频道。
再看一下时序图
我们可以看到命令模式的执行顺序
1. Client创建一个ConcreteCommand对象并指定他的Receiver对象 2. 某个Invoker对象存储该ConcreteCommand对象 3. 该Invoker通过调用Command对象的Execute操作来提交一个请求。若该命令是可撤销的,ConcreteCommand就在执行Execute操作之前存储
当前状态以用于取消该命令 4. ConcreteCommand对象对调用它的Receiver的一些操作以执行该请求
看一下代码
public class Client
{
static void Main(string[] args)
{
Receiver _receiver = new Receiver();
ConcreteCommand _conCmd = new ConcreteCommand(_receiver);
Invoker _invoker = new Invoker();
_invoker.SetCommand(_conCmd);
_invoker.RunCommand();
Console.ReadLine();
}
}
#region 命令模式
public interface Command
{
void Execute();
}
public class Invoker
{
private Command command = null;
public void SetCommand(Command f_Command)
{
command = f_Command;
}
public void RunCommand()
{
command.Execute();
}
}
public class Receiver
{
public void Action()
{
Console.WriteLine("Receiver:Action Run....");
}
}
public class ConcreteCommand : Command
{
private Receiver reciver;
public ConcreteCommand(Receiver f_receiver)
{
reciver = f_receiver;
}
#region Command 成员
public void Execute()
{
reciver.Action();
}
#endregion
}
#endregion
执行结果
模式优点 1.降低对象之间的耦合度。 2.新的命令可以很容易地加入到系统中。 3.可以比较容易地设计一个组合命令。 4.调用同一方法实现不同的功能
模式缺点 1.系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互。 2.系统需要在不同的时间指定请求、将请求排队和执行请求。 3.系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作。 4.系统需要将一组操作组合在一起,即支持宏命令。
- R语言中的遗传算法
- 跟Google学写代码--Chromium工程中用到的C++11特性
- 兼容IE6 a标签hover特殊效果
- 基于机器学习方法的POI品类推荐算法
- 细说ReactiveCocoa的冷信号与热信号系列(3)
- pageResponse - 移动端适配框架
- R语言与机器学习(分类算法)logistic回归
- 一步步教你弹性框架-上篇
- 【编程基础】C++初学者需掌握的10个C++特性(中)
- 一步步教你弹性框架-中篇
- 细说ReactiveCocoa的冷信号与热信号系列(2)
- 谈谈个人网站的建立(三)—— 定时任务
- 细说ReactiveCocoa的冷信号与热信号系列(1)
- 【美团技术团队博客】前端组件化开发实践
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 如何同时压测创建和删除接口
- 为什么测试覆盖率如此重要
- 5行Python就能爬取 3000+ 上市公司的信息?
- iOS 代码染色原理及技术实践
- 微信小程序【常用组件及自定义组件】
- 虚拟机字节码执行引擎,JVM的马达图,是爱情呀
- 微信小程序【浅提WXSS样式】
- Kubernetes Liveness and Readiness Probes
- Magicodes.IE 2.3重磅发布——.NET Core开源导入导出库
- pytest文档59-运行未提交git的用例(pytest-picked)
- pytest文档57-单元测试代码覆盖率(pytest-cov)
- pytest文档58-随机执行测试用例(pytest-random-order)
- Kubernetes探针踩坑记
- 大揭秘| 我司项目组Gitlab Flow && DevOps流程
- 离线安装Superset 0.37(截图详细版)