第14章 命令模式(Command Pattern)

原文 第14章
命令模式(Command Pattern)

命令模式(Command Pattern)

概述

 

在软件系统中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”。但在某些场合,比如要对行为进行“记录、撤销/重做、事务”等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将“行为请求者”与“行为实现者”解耦?将一组行为抽象为对象,可以实现二者之间的松耦合[李建忠]。这就是本文要说的Command模式。

将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。[GOF 《设计模式》]

结构图

    

         

 

   举例

   
 
电脑开机,关机,重启的功能控制





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

  /// <summary>

    /// 电脑

    /// </summary>

    public class Computer

    {

        public void Start()

        {

            //开机

            Console.WriteLine("开机");  

        }

        public void Stop()

        {  

            //关机

            Console.WriteLine("关机");

        }

        public void ReStart()

        

            //重启

            Console.WriteLine("重启");

        }

    }

    

      /// <summary>

    /// 执行命令的抽象类

    /// </summary>

    public abstract class Command

    {

        public Computer computer;

        public Command(Computer computer)

        {

            this.computer = computer;

        }

        //执行命令

        public abstract void Excute();

    }

    /// <summary>

    /// 开机

    /// </summary>

    public class Start : Command

    {

        //调用父类的赋值方法

        public Start(Computer computer)

            base(computer)

        { }

        public override void Excute()

        {

            computer.Start();

        }

    }

    /// <summary>

    /// 关机

    /// </summary>

    public class Stop : Command

    {

        //调用父类的赋值方法

        public Stop(Computer computer)

            base(computer)

        { }

        public override void Excute()

        {

            computer.Stop();

        }

    }

    /// <summary>

    /// 重启

    /// </summary>

    public class ReStart : Command

    {

        public ReStart(Computer computer) : base(computer) { }

        public override void Excute()

        {

            computer.ReStart();

        }

    }

    /// <summary>

    /// 控制器

    /// </summary>

    public class Control

    {

        public Command start, stop, reStart;

        public Control(Command start, Command stop, Command reStart)

        {

            this.start = start;

            this.stop = stop;

            this.reStart = reStart;

        }

        public void Start()

        {

            start.Excute();

        }

        public void Stop()

        {

            stop.Excute();

        }

        public void ReStart()

        {

            reStart.Excute();

        }

    }

    

       //客户端调用

        static void Main(string[] args)

        {

            Computer computer = new Computer();

            Command start = new Start(computer);

            Command stop = new Stop(computer);

            Command reStart = new ReStart(computer);

            Control control = new Control(start, stop, reStart);

            control.Start();//开机

            control.Stop();//关机

            control.ReStart();//重启

            Console.ReadLine();

        }

使用命令模式的效果

 

1.Command模式的根本目的在于将“行为请求者”与“行为实现者”解耦,在面向对象语言中,常见的实现手段是“将行为抽象为对象”。

2.实现Command接口的具体命令对象ConcreteCommand有时候根据需要可能会保存一些额外的状态信息。

3.通过使用Compmosite模式,可以将多个命令封装为一个“复合命令”MacroCommand。

4.Command模式与C#中的Delegate有些类似。但两者定义行为接口的规范有所区别:Command以面向对象中的“接口-实现”来定义行为接口规范,更严格,更符合抽象原则;Delegate以函数签名来定义行为接口规范,更灵活,但抽象能力比较弱。

5.使用命令模式会导致某些系统有过多的具体命令类。某些系统可能需要几十个,几百个甚至几千个具体命令类,这会使命令模式在这样的系统里变得不实际。


   适用场景

在下面的情况下应当考虑使用命令模式:

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

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

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

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

   总结

Command模式的根本目的在于将“行为请求者”与“行为实现者”解耦。

设计模式系列文章http://www.diyibk.com/post/39.html

时间: 2024-11-07 18:43:48

第14章 命令模式(Command Pattern)的相关文章

设计模式 - 命令模式(command pattern) 撤销(undo) 具体解释

命令模式(command pattern) 撤销(undo) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 參考命令模式: http://blog.csdn.net/caroline_wendy/article/details/31379977 命令模式能够用于运行撤销(undo)操作. 详细方法: 1. 对象类中须要保存状态, 如level. package command; public class CeilingFan { String lo

设计模式 - 命令模式(command pattern) 具体解释

命令模式(command pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 命令模式(command pattern) : 将请求封装成对象, 以便使用不同的请求\队列\日志来參数化其它对象. 命令模式也能够支持撤销操作. 简单的命令模式的实现: 1. 详细的类, 每个类都有特定的方法: /** * @time 2014年6月9日 */ package command; /** * @author C.L.Wang * */ publ

设计模式 - 命令模式(command pattern) 详解

命令模式(command pattern) 详解 本文地址: http://blog.csdn.net/caroline_wendy 命令模式: 将请求封装成对象, 以便使用不同的请求\队列\日志来参数化其他对象. 命令模式也支持可撤销操作. 命令模式: 调用者(Invoker); 命令(Command): 可执行方法(execute), 具体命令(Concrete Command); 接受者(Receiver): 调用命令(Set Command); 具体方法: 1. 具体对象. /** *

设计模式 - 命令模式(command pattern) 多命令 详解

命令模式(command pattern) 多命令 详解 本文地址: http://blog.csdn.net/caroline_wendy 参考命令模式: http://blog.csdn.net/caroline_wendy/article/details/31379977 具体步骤: 1. 多命令, 把未使用的命令, 初始化为空对象(NoCommand), 根据参数(slot), 选择输出命令. /** * @time 2014年6月16日 */ package command; /**

设计模式 - 命令模式(command pattern) 撤销(undo) 详解

命令模式(command pattern) 撤销(undo) 详解 本文地址: http://blog.csdn.net/caroline_wendy 参考命令模式: http://blog.csdn.net/caroline_wendy/article/details/31379977 命令模式可以用于执行撤销(undo)操作. 具体方法: 1. 对象类中需要保存状态, 如level. package command; public class CeilingFan { String loca

设计模式 - 命令模式(command pattern) 宏命令(macro command) 详解

命令模式(command pattern) 宏命令(macro command) 详解 本文地址: http://blog.csdn.net/caroline_wendy 参考: 命名模式(撤销): http://blog.csdn.net/caroline_wendy/article/details/31419101 命令模式可以执行宏命令(macro command), 即多个命令的组合操作. 具体方法:  1. 其余代码与命令(撤销)一致 2. 添加宏命令(macro command),

设计模式 - 命令模式(command pattern) 多命令 具体解释

命令模式(command pattern) 多命令 具体解释 本文地址: http://blog.csdn.net/caroline_wendy 參考命令模式: http://blog.csdn.net/caroline_wendy/article/details/31379977 具体步骤: 1. 多命令, 把未使用的命令, 初始化为空对象(NoCommand), 依据參数(slot), 选择输出命令. /** * @time 2014年6月16日 */ package command; /*

设计模式之命令模式---Command Pattern

模式的定义 命令模式是一个高内聚的模式,定义如下: Encapsulate a request as an object,thereby letting you parameterize clients with different requests,queue or log requests,and support undoable operations 将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录日志,可以提供命令的撤销和恢复功能. 模式的使用场景 只要

设计模式(行为型)之命令模式(Command Pattern)

PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN.因为CSDN也支持MarkDown语法了,牛逼啊! [工匠若水 http://blog.csdn.net/yanbober] 阅读前一篇<设计模式(行为型)之策略模式(Strategy Pattern)>http://blog.csdn.net/yanbober/article/details/45498567 概述 在软件开发中,我们经常需要向某些对象发送请求(调用其中的某个或某些方法),但是并不知道请求的接收