zoukankan      html  css  js  c++  java
  • C#面向对象设计模式纵横谈 笔记15 Command 命令(行为型模式)

    耦合与变化

    耦合是软件不能抵御变化灾难的根本性原因。不仅实体对象与实体对象之间存在耦合关系,实体对象与行为操作之间也存在耦合关系。

    动机(Motivation

       在软件构建过程中,行为请求者行为实现者” 通常呈现一种紧耦合。但在某些场合—— 比如需要对行为进行记录、撤销/重做(undo/redo)、事务等处理,这种无法抵御变化的紧耦合是不合适的。

       在这种情况下,如何将行为请求者行为实现者解耦?将一组行为抽象为对象,可以实现二者之间的松耦合。“直接依赖”——>间接依赖”

    意图(Intent

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

    例说Command应用  Codes in .NET

    1)Document 类

        /// <summary>
        /// 已经存在的文件处理类
        /// </summary>
        public class Document
        {
            public virtual void ShowText()
            {
                //...........
            }
        }
    

    2Graphics 

     /// <summary>
    /// 已经存在的图像处理类
    /// </summary>
    public class Graphics
    {
            public virtual void ShowGraphics()
            {
                //...........
            }
     }
    

    3)ICommand 接口

        /// <summary>
        /// 可以写为接口或者抽象类
        /// 一般不包括默认的实现
        /// </summary>
        public interface ICommand
        {
           public void Show();
           public void Undo();
           public void Redo();
        }
    

    4) DocumentCommand 

        /// <summary>
        /// 具体的命令对象 -- 从抽象意义来讲,DocumentCommand表示一个行为对象
        /// </summary>
        class DocumentCommand : ICommand
        {
            public Document _doc { get; set; }
    
            public DocumentCommand(Document doc)
            {
                this._doc = doc;
            }
    
            public void Show()
            {
                _doc.ShowText();
            }
    
            public void Undo()
            {
                //Document 对应的逻辑
            }
            public void Redo()
            {
                //Document 对应的逻辑
            }
        }

    5) GraphicsCommand 

        /// <summary>
        /// 具体的命令对象 -- GraphicsCommand表示一个行为对象
        /// </summary>
        class GraphicsCommand : ICommand
        { 
            public Graphics _graphics;
            public GraphicsCommand(Graphics graphics)
            {
                this._graphics = graphics;
            }
    
            public void Show()
            {
                //..........
            }
    
            public void Undo()
            {
                //..........
            }
    
            public void Redo()
            {
                //...........
            }
        }
    

    6)应用程序主干

        /// <summary>
        /// 应用程序主干(高层抽象),间接依赖具体的实现
        /// </summary>
        class Application
        {
            Stack<ICommand> stack;
            Stack<ICommand> undoList;
    
            /// <summary>
            /// 存储实现了ICommand接口的对象
            /// </summary>
            List<ICommand> list;
    
            public void Show()
            {
                foreach (ICommand item in list)
                {
                    item.Show();
                }
            }
    
            public void Undo()
            {
                if (stack.Count != 0)
                {
                    ICommand command = stack.Pop();
                    command.Undo();
                    undoList.Push(command);
                }
    
            }
            public void Redo()
            {
                if (undoList.Count != 0)
                {
                    ICommand command = undoList.Pop();
                    command.Redo();
                }
            }
        }
    

    结构(Structure

     

     

     

     

     

     

     

     

     

     

     

     


     

    Command模式的几个要点

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

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

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

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


    推荐资源

    1)《设计模式:可复用面向对象软件的基础》GoF

    2)《面向对象分析与设计》Grady Booch 

    3)《敏捷软件开发:原则、模式与实践》Robert C. Martin 

    4)《重构:改善既有代码的设计》Martin Fowler 

    5)Refactoring to PatternsJoshua Kerievsky

  • 相关阅读:
    廖雪峰Java12maven基础-1maven入门-2依赖管理
    廖雪峰Java12maven基础-1maven入门-1maven介绍
    廖雪峰Java11多线程编程-4线程工具类-1ThreadLocal
    廖雪峰Java11多线程编程-3高级concurrent包-9Fork_Join
    廖雪峰Java11多线程编程-3高级concurrent包-8CompletableFuture
    廖雪峰Java11多线程编程-3高级concurrent包-7Future
    modelsim remote
    单台电脑上启动多个Modelsim图形环境窗口的简单办法(windows)
    用ModelSim仿真SDRAM操作
    通过文件读写方式实现Matlab和Modelsim的联合仿真
  • 原文地址:https://www.cnblogs.com/lujiao_cs/p/2172921.html
Copyright © 2011-2022 走看看