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

  • 相关阅读:
    Serialization and deserialization are bottlenecks in parallel and distributed computing, especially in machine learning applications with large objects and large quantities of data.
    Introduction to the Standard Directory Layout
    import 原理 及 导入 自定义、第三方 包
    403 'Forbidden'
    https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2
    These interactions can be expressed as complicated, large scale graphs. Mining data requires a distributed data processing engine
    mysqldump --flush-logs
    mysql dump 参数
    mysql dump 参数
    如果是在有master上开启了该参数,记得在slave端也要开启这个参数(salve需要stop后再重新start),否则在master上创建函数会导致replaction中断。
  • 原文地址:https://www.cnblogs.com/lujiao_cs/p/2172921.html
Copyright © 2011-2022 走看看