设计模式-行为型-命令模式

命令模式(Command):

  将请求封装成对象,以便使用不同的请求、日志、队列等来参数化其他对象。命令模式也支持撤销操作。

命令模式的角色:

  

  1)传递命令对象(Invoker):是请求的发送者,它通常拥有很多的命令对象,并通过访问命令对象来执行相关请求,它不直接访问接收者。

  2)抽象命令接口(Command):声明执行命令的接口,拥有执行命令的抽象方法execute()。

  3)具体的命令对象(ConcreteCommand):是抽象命令类的具体实现类,它拥有接收者对象,并通过调用接收者的功能来完成命令要执行的操作。

  4)接受者对象(Receiver):执行命令功能的相关操作,是具体命令对象业务的真正实现者。

  5)客户端对象(Client):创建具体命令的对象并且设置命令对象的接受者。

示例:

  土豪小明是一个狂热的科技迷,因此将家中电器进行了全面升级,更换成了智能家电,通过小爱同学可以统一控制,只需要一句"小爱同学,打开电灯"...,那么我们的故事就从这里开始。

  

  1 internal class Program
  2 {
  3     private static void Main(string[] args)
  4     {
  5         // 创建电灯的对象
  6         LightReceiver lightReceiver = new LightReceiver();
  7         // 创建电灯的开关命令
  8         Command lightOnCommand = new LightOnCommand(lightReceiver);
  9         Command lightOffCommand = new LightOffCommand(lightReceiver);
 10         // 创建遥控器-小爱同学
 11         RemoteController remoteController = new RemoteController();
 12         // 设置
 13         remoteController.setCommand(0, lightOnCommand, lightOffCommand);
 14         // 执行命令
 15         remoteController.onExecute(0);
 16         remoteController.Undo();
 17     }
 18 }
 19
 20 /// <summary>
 21 /// 抽象命令接口
 22 /// </summary>
 23 public interface Command
 24 {
 25     /// <summary>
 26     /// 执行
 27     /// </summary>
 28     void execute();
 29
 30     /// <summary>
 31     /// 撤销
 32     /// </summary>
 33     void undo();
 34 }
 35
 36 /// <summary>
 37 /// 接受者对象
 38 /// </summary>
 39 public class LightReceiver
 40 {
 41     public void on()
 42     {
 43         Console.WriteLine("电灯打开了...");
 44     }
 45
 46     public void off()
 47     {
 48         Console.WriteLine("电灯关闭了...");
 49     }
 50 }
 51
 52 /// <summary>
 53 /// 具体的命令对象
 54 /// </summary>
 55 internal class LightOnCommand : Command
 56 {
 57     private readonly LightReceiver lightReceiver;
 58
 59     public LightOnCommand(LightReceiver lightReceiver)
 60     {
 61         this.lightReceiver = lightReceiver;
 62     }
 63
 64     public void execute()
 65     {
 66         // 调用接收者的方法
 67         lightReceiver.on();
 68     }
 69
 70     public void undo()
 71     {
 72         // 调用接收者的方法
 73         lightReceiver.off();
 74     }
 75 }
 76
 77 /// <summary>
 78 /// 具体的命令对象
 79 /// </summary>
 80 internal class LightOffCommand : Command
 81 {
 82     private readonly LightReceiver lightReceiver;
 83
 84     public LightOffCommand(LightReceiver lightReceiver)
 85     {
 86         this.lightReceiver = lightReceiver;
 87     }
 88
 89     public void execute()
 90     {
 91         // 调用接收者的方法
 92         lightReceiver.off();
 93     }
 94
 95     public void undo()
 96     {
 97         // 调用接收者的方法
 98         lightReceiver.on();
 99     }
100 }
101
102 /// <summary>
103 /// 空命令,用于初始化
104 /// </summary>
105 internal class NoCommand : Command
106 {
107     public void execute()
108     {
109     }
110
111     public void undo()
112     {
113     }
114 }
115
116 internal class RemoteController
117 {
118     // 按钮的命令数组
119     private Command[] onCommands;
120
121     private Command[] offCommands;
122
123     // 撤销命令
124     private Command undoCommand;
125
126     public RemoteController()
127     {
128         // 假设小爱同学需要连接5款智能家电
129         onCommands = new Command[5];
130         offCommands = new Command[5];
131         for (int i = 0; i < 5; i++)
132         {
133             onCommands[i] = new NoCommand();
134             offCommands[i] = new NoCommand();
135         }
136     }
137
138     // 给小爱同学设置需要的命令
139     public void setCommand(int no, Command onCommand, Command offCommand)
140     {
141         onCommands[no] = onCommand;
142         offCommands[no] = offCommand;
143     }
144
145     // 对小爱同学下达打开命令
146     public void onExecute(int no)
147     {
148         // 小爱同学执行打开操作
149         onCommands[no].execute();
150         // 记录操作,用于撤回
151         undoCommand = onCommands[no];
152     }
153
154     // 对小爱同学下达关闭命令
155     public void offExecute(int no)
156     {
157         // 小爱同学执行关闭操作
158         offCommands[no].execute();
159         // 记录操作,用于撤回
160         undoCommand = offCommands[no];
161     }
162
163     /// <summary>
164     /// 撤销上次操作
165     /// </summary>
166     public void Undo()
167     {
168         undoCommand.undo();
169     }
170 }

命令模式的优缺点:

  优点:

    1)降低系统的耦合度。命令模式能将调用操作的对象与实现该操作的对象解耦。

    2)增加或删除命令非常方便。采用命令模式增加与删除命令不会影响其他类,它满足OCP原则,对扩展比较灵活。

    3)可以实现宏命令。命令模式可以与组合模式结合,将多个命令装配成一个组合命令,即宏命令。

    4)方便实现 Undo 和 Redo 操作。命令模式可以与备忘录模式结合,实现命令的撤销与恢复。

  缺点:可能产生大量的具体命令类。

适用环境:

  1)使用命令模式作为“CallBack”在面向对象系统中的替代。“CallBack”讲的便是先将一个函数登记上,然后在以后调用此函数。

  2)需要在不同的时间指定请求、将请求排队。一个命令对象和原先的请求发出者可以有不同的生命期。换言之,原先的请求发出者可能已经不在了,而命令对象本身仍然是活动的。这时命令的接收者可以是在本地,也可以在网络的另外一个地址。命令对象可以在串形化之后传送到另外一台机器上去。

  3)系统需要支持命令的撤消(undo)。命令对象可以把状态存储起来,等到客户端需要撤销命令所产生的效果时,可以调用undo()方法,把命令所产生的效果撤销掉。命令对象还可以提供redo()方法,以供客户端在需要时,再重新实施命令效果。

  4)如果一个系统要将系统中所有的数据更新到日志里,以便在系统崩溃时,可以根据日志里读回所有的数据更新命令,重新调用Execute()方法一条一条执行这些命令,从而恢复系统在崩溃前所做的数据更新。

命令模式与策略模式的区别:

  1)命令模式与策略模式都封装了变化,但命令模式封装的是请求的变化,而策略模式封装的是算法的变化。

  2)命令模式可以抽象化成策略模式。策略模式较简单,而命令模式比较复杂。策略模式聚焦的是对相同请求更换解决方案的灵活性;而命令模式聚焦的是对多请求变化的封装以及对相同请求不同的请求形式解决方法的可复用性。

参考:https://blog.csdn.net/zhwyj1019/article/details/79758057

原文地址:https://www.cnblogs.com/az4215/p/11619647.html

时间: 2024-08-14 19:41:16

设计模式-行为型-命令模式的相关文章

设计模式-行为型-命令模式(COMMAND)

命令模式是一个结构比较简单的设计模式,gof在书中对它的定义是:"将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可撤消的操作." 这里有两个要点,第一请求被封装成了一个对象,第二请求可以被持久化(排队或是记录.取消). 我们从第一个要点说起.首先需要注意一点的所有COMMAND的模型都可以抽象出一个Execute概念或是类似概念.如下图(左)一样,这里的请求就是对文档做出paste操作,封装的结果就是通过PasteCommand的一

[设计模式-行为型]命令模式(Command)

一句话 命令的请求和命令的执行用不同的对象表示.(好处是可以独立开发,也可以进行撤销) 概括 解析 COMMAND-俺有一个MM家里管得特别严,没法见面,只好借助于她弟弟在我们俩之间传送信息,她对我有什么指示,就写一张纸条让她弟弟带给我.这不,她弟弟又传送过来一个COMMAND,为了感谢他,我请他吃了碗杂酱面,哪知道他说:"我同时给我姐姐三个男朋友送COMMAND,就数你最小气,才请我吃面."命令模式:命令模式把一个请求或者操作封装到一个对象中.命令模式把发出命令的责任和执行命令的责任

编程模式之15---行为型----命令模式

定义 将一个请求封装成一个对象,让你可以用不同的请求对客户端进行参数化,对请求排队,纪录请求日志和支持可撤消操作. 有三个具体成员,请求的发送者,请求的接收者,还有就是请求本身(或者是命令).对客户端进行参数化,也就是客户端可以把请求对象当成一个参数,直接注入到请求发送者内部,不用管请求接收者;对请求排队,如果一个请求发送者发送了一个请求,有多个接收者会处理这个请求的话,那么就需要对命令排队,命令对象和请求接收者是一一对应的;纪录请求日志,当发出一个请求时,由命令对象来保存一些信息,证明本对象被

设计模式(14)--Command(命令模式)--行为型

作者QQ:1095737364    QQ群:123300273     欢迎加入! 1.模式定义:   命令模式属于对象的行为模式.命令模式又称为行动(Action)模式或交易(Transaction)模式.   命令模式把一个请求或者操作封装到一个对象中.命令模式允许系统使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能. 2.模式特点: 在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序

设计模式之行为型命令模式

将请求与实现解耦并封装成独立对象,从而使不同的请求对客户端的实现参数化.命令模式是将创建模块的逻辑封装在一个对象里,这个对象提供一个参数化的请求接口,通过调用这个接口并传递一些参数实现调用命令对象内部中的一些方法.请求部分很简单,只需要按照给定参数格式书写指令即可,所以实现部分的封装才是重点,因为它要为请求部分提供所需方法. // 模块实现模块 var viewCommand = (function() { var tpl = { // 展示图片结构模块 product: [ '<div>',

JAVA设计模式(15):行为型-命令模式(Command)

介绍 命令模式:将一个请求封装为一个对象,从而使我们可用不同的请求对客户进行参数化:对请求排队或者记录请求日志,以及支持可撤销的操作.也称之为:动作Action模式.事务transaction模式. 结构 Command抽象命令类 定义命令的接口,声明执行的方法. ConcreteCommand具体命令类 命令接口实现对象,是"虚"的实现:通常会持有接收者,并调用接收者的功能来完成命令要执行的操作. Invoker调用者/请求者 请求的发送者,它通过命令对象来执行请求.一个调用者并不需

设计模式学习之命令模式

模式动机 在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计,使得请求发送者与请求接收者消除彼此之间的耦合,让对象之间的调用关系更加灵活. 命令模式可以对发送者和接收者完全解耦,发送者与接收者之间没有直接引用关系,发送请求的对象只需要知道如何发送请求,而不必知道如何完成请求.这就是命令模式的模式动机. 模式定义 命令模式(Command Pattern):将一个请求

设计模式-行为型-策略模式

策略模式(Strategy): 策略模式是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理.策略模式通常把一个系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类.用一句话来说,就是:“准备一组算法,并将每一个算法封装起来,使得它们可以互换”. 策略模式的角色: 1)环境类(Context):采用组合或聚合的方式维护一个对Strategy对象的引用. 2)抽象策略类(Strategy):定义所有支持的算法的公共接口.Context使用这个接口来调用某Concret

从王者荣耀看设计模式(九.命令模式)

从王者荣耀看设计模式(命令模式) 一.简介 王者荣耀是一款团队竞技游戏.良好的团队信息交流在一定程度上能帮助队伍取得胜利.为了保证游戏的流畅性与便捷性,王者荣耀提供了快捷交流机制,在王者小地图旁边有几个快捷聊天按钮(开始撤退,发起进攻,请求结合),玩家可通过点击快捷聊天按钮发出相应命令与队友进行交流 二.命令模式 命令模式(Command Pattern):命令模式是一种高内聚的模式,将"请求"封装成对象,以便使用不同的请求.队列或者日志来参数化其他对象.命令模式也支持可撤销的操作.