命令模式又称为行动(Action)模 式或交易(Transaction)模式。命令模式把一个请求或者操作封装到一个对象中。

命令模式是对命令的封装。命令模式把发出命令的责任和执行命令的责任分割开,委派给不同的对象.

每一个命令都是一个操作:请求的一方发出请求要求执行一个操作;接收的一方收到请求,并执行操作。命令模式允许

请求的一方和接收的一方独立开来,使 得 请 求的一方不必知道接收请求的一方的接口,更不必知道请求是怎么被接收,以及操作是否被执行、何时被执行,以及是怎么被执行的。

命令模式类图:

命令模式涉及到五个角色,它们分别是:
  • 客户(Client)角色:创建了一个具体命令 (ConcreteCommand)对象并确定其接收者。

  • 命令(Command)角色:声明了一个给所有具体命令类 的抽象接口。这是一个抽象角色。

  • 具体命令(ConcreteCommand)角色:定义一个接受者和行为之间的弱耦合;实现 Execute()方法,负责调用接收考的相应操作。Execute()方法通常叫做执方法。

  • 请求者(Invoker)角色:负责调用命令对象执行请求, 相关的方法叫做行动方法。

  • 接收者(Receiver)角色:负责具体实施和执行一个请求。任何一个类都可以成为接收者,实施和执行请求的方法叫做行动方法。

示例代码:

class Program
{
static void Main(string[] args)
{
Receiver r = new Receiver();
Command command = new ConcreteCommand(r);
Invoker i = new Invoker();
i.SetCommand(command);
i.ExecuteCommand();
Console.ReadKey();
}
} abstract class Command
{
protected Receiver receiver;
public Command(Receiver receiver)
{
this.receiver = receiver;
}
abstract public void Execute();
} class ConcreteCommand : Command
{
public ConcreteCommand(Receiver receiver)
: base(receiver)
{ }
public override void Execute()
{
receiver.Action();
}
} class Receiver
{
public void Action()
{
Console.WriteLine("Called Receiver.action()"); }
} class Invoker
{
private Command command;
public void SetCommand(Command command)
{
this.command = command;
} public void ExecuteCommand()
{
command.Execute();
}
}

运行结果:

在下面的情况下应当考虑使用命令模式:
  1、使用命令模式作为"CallBack"在面向对象系统中的替代。"CallBack"讲的便是先将一个函数 登记上,然后在以后调用此函数。
  2、需要在不同的时间指定请求、将请求排队。一个命令对象和原先的请求发出者可以有不同的生命期。换言之,原先的请求发出者可能已经不在了,

    而命令对象本身仍然是活动的。这时命令的接收者可以是在本地,也 可以在网络的另外一个地址。命令对象可以在串形化之后传送到另外一台机器上去。
  3、系统需要支持命令的撤消(undo)。命令对象可以把状态存储起来,等到客户端需要撤销命 令所产生的效果时,可以调用 undo()方法,把命令所产生的效果撤销掉。命令对象还可以提供 redo()方法,以供客户端在需要时,再重新实施命令效果。
  4、如果一个系统要将系统中所有的数据更新到日志里,以便在系统崩溃时,可以根据日志里读 回所有的数据更新命令,重新调用 Execute()方法一条一条执行这些命令,从而恢复系统在崩 溃前所做的数据更新。
  5、一个系统需要支持交易(Transaction)。一个交易结构封装了一组数据更新命令。使用命令 模式来实现交易结构可以使系统增加新的交易类型。

使用命令模式的优点和缺点
命令允许请求的一方和接收请求的一方能够独立演化,从而且有以下的优点:
  • 命令模式使新的命令很容易地被加入到系统里。

  • 允许接收请求的一方决定是否要否决(Veto)请求。

  • 能较容易地设计-个命令队列。

  • 可以容易地实现对请求的Undo 和 Redo。

  • 在需要的情况下,可以较容易地将命令记入日志。

  • 命令模式把请求一个操作的对象与知道怎么执行一个操作的对象分割开。

  • 命令类与其他任何别的类一样,可以修改和推广。

  • 你可以把命令对象聚合在一起,合成为合成命令。比如宏命令便是合成命令的例子。合 成命令是合成模式的应用。

  • 由于加进新的具体命令类不影响其他的类,因此增加新的具体命令类很容易。
命令模式的缺点如下:
  • 使用命令模式会导致某些系统有过多的具体命令类。某些系统可能需要几十个,几百个 甚至几千个具体命令类,这会使命令模式在这样的系统里变得不实际。

十五、命令(Command)模式--行为型模式(Behavioral Pattern)的更多相关文章

  1. FactoryMethod工厂方法模式(创建型模式)

    1.工厂方法模式解决的问题 现在有一个抽象的游戏设施建造系统,负责构建一个现代风格和古典风格的房屋和道路. 前提:抽象变化较慢,实现变化较快(不稳定) 整个抽象的游戏设施建造系统相对变化较慢,本例中只 ...

  2. Prototype原型模式(创建型模式)

    1.原型模式解决的问题 现在有一个抽象的游戏设施建造系统,负责构建一个现代风格和古典风格的房屋和道路. 前提:抽象变化较慢,实现变化较快(不稳定) 整个抽象的游戏设施建造系统相对变化较慢,本例中只有一 ...

  3. C#设计模式之十五命令模式(Command Pattern)【行为型】

    一.引言   今天我们开始讲"行为型"设计模式的第二个模式,该模式是[命令模式],又称为行动(Action)模式或交易(Transaction)模式,英文名称是:Command P ...

  4. 设计模式(十四):Command命令模式 -- 行为型模式

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

  5. 设计模式学习之命令模式(Command,行为型模式)(12)

    一.命令模式的定义 命令模式属于对象的行为型模式.命令模式是把一个操作或者行为抽象为一个对象中,通过对命令的抽象化来使得发出命令的责任和执行命令的责任分隔开.命令模式的实现可以提供命令的撤销和恢复功能 ...

  6. 设计模式(五):PROTOTYPE原型模式 -- 创建型模式

    1.定义 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 2.适用场景 原型模式的主要思想是基于现有的对象克隆一个新的对象出来,一般是有对象的内部提供克隆的方法,通过该方法返回一个对 ...

  7. 悟空模式-java-原型模式

    [却说那妖精与大圣斗经半日,不分胜败.行者把棒丢起,叫一声“变!”就以一变十,以十变百,以百变千,半天里,好似蛇游蟒搅,乱打妖邪.妖邪慌了手脚,将身一闪,化道清风,即奔碧空之上逃走.行者念声咒语,将铁 ...

  8. 工厂方法模式——创建型模式02

    1. 简单工厂模式     在介绍工厂方法模式之前,先介绍一下简单工厂模式.虽然简单工厂模式不属于GoF 23种设计模式,但通常将它作为学习其他工厂模式的入门,并且在实际开发中使用的也较为频繁. (1 ...

  9. 建造者模式与原型模式/builder模式与prototype模式/创建型模式

    建造者模式 定义 用于简化复杂对象的创建 JDK中的建造者模式 java.lang.StringBuilder中的append()方法,每次调用后返回修改后的对象本身. public StringBu ...

  10. 设计模式(二): BUILDER生成器模式 -- 创建型模式

    1.定义 将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式. 2.适用场景 1. 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式 ...

随机推荐

  1. 使用Eclipse开发Maven插件-1/3

    概要 1. 这是一个样例,基本照着<Maven实战>-徐晓斌,第17章照抄的:个人练手之作,不喜勿喷! 2. 代码行统计插件. 备注   大量插件可从以下网站获得:     1. http ...

  2. 自定义Filter服务

    自定义一个用户Email长度超过12个字符后值截取前12个然后添加“...”显示. 例如: index.html <!DOCTYPE html> <html ng-app=" ...

  3. .NET 使用unity实现依赖注入

    原文地址:http://www.cnblogs.com/wujy/p/3317795.html 一:理论部分 依赖注入:这是 Ioc 模式的一种特殊情况,是一种基于改变对象的行为而不改变类的内部的接口 ...

  4. Eclipse代码提示功能设置(Java & Eclipse+CDT C/C++)

    http://developer.51cto.com/art/200907/136242.htm http://blog.chinaunix.net/u/21684/showart_462486.ht ...

  5. 在wp中,使用NavigationService.Navigate导航页面出现错误

    我们在WP项目中采用页面导航时候,经常会使用以下代码 NavigationService.Navigate(new Uri("/Page1.xaml",UriKind.Relati ...

  6. Jquery radio checked

    Jquery radio checked     radio 1. $("input[name='radio_name'][checked]").val(); //选择被选中Rad ...

  7. python字符集选择

    # coding=utf8 或者 # -*- coding:utf-8 -*- 在python2 中默认是ASCII码的字符集,但可以引入其他的字符集  这个需要在头信息中引入: 而在python3中 ...

  8. OCP-1Z0-051-题目解析-第6题

    6. Examine the structure of the SHIPMENTS table: name                    Null        Type PO_ID      ...

  9. leetcode先刷_Unique Paths II

    那么上述问题,假设这个矩阵堵塞障碍,不能在若干组合前面所用的方法,因为这么多的位置实际上是没有办法的事儿. 还有剩下的唯一合理的解决方案dp该.与最低要求,并且等,从右下角以前突起,对于位置(i, j ...

  10. 达到XML简单的动态配置

    今天写的XML相关内容:随着上述眼前的小项目(等级类别)由于地图每个级别.因此,让他动态读取XML内容,这样的变化只能看到XML档. 简单的想法:第一次使用UserDefault类写入文件 UserD ...