• 设计模式学习笔记七:备忘录模式组合模式迭代器模式桥接模式命令模式职责链模式享元模式


    一.备忘录模式

      1.概念

        备忘录(Memento),即在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到先前保存的状态.

      2.应用

        备忘录其实就是对象的存档.首先需要区分对象中哪些状态(字段或属性)的值需要保存,将这些状态抽象为一个新的备忘录(Memento)类,用这个类对象保存这些状态值,可以提供一个备忘录对象的管理类,将所有备忘录对象使用键值对等方式存储起来.必要时找到相应的备忘录,然后就可以还原对象某个时刻的状态.

    二.组合模式

      1.概念

        组合模式(Composite),是一种结构型模式,将对象组合成属性结构表示"部分-整体"的层次结构.组合模式使得用户对单个对象和组合对象的使用具有一致性.

      2.应用

        组合模式的应用可以理解为就是树的应用.定义一个公共的接口,这个接口可以有两种实现类,一种是非叶子节点,在实现方法中调用子节点的相应方法;一种是叶子节点,在实现方法中实际完成相应的功能.组合模式适用于对一些树形结构的功能抽象.

    三.迭代器模式

      1.概念

        迭代器模式(Iterator),提供了一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示.

      2.应用

        迭代器应该是很常用的,在C#中的foreach循环就是使用了迭代器.迭代器模式是针对容器的遍历的,我们只需要提供一个Iterator接口,其中定义了Next()等方法,然后在定义好的遍历方法中调用迭代器接口中的方法.对于自定义的容器,要想能够被foreach遍历,只需要实现迭代器接口实现这些方法即可.在C#中,ListDictionary等数据容器都实现了迭代器接口.

    四.桥接模式

      1.概念

        桥接模式(Bridge),其将抽象部分与它的实现部分分离,使它们都可以独立地变化.

      2.示例类图

      3.示例代码:

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace DesignPatternsCore
    {
        /// <summary>
        /// 抽象维度父类
        /// </summary>
        public class Abstraction
        {
            public Implementor imp;
            public virtual void Operation()
            {
                imp.OperationImp();
            }
        }
        /// <summary>
        /// 提炼出来的抽象维度类
        /// </summary>
        public class RefinedAbstraction : Abstraction
        {
            public override void Operation()
            {
                base.Operation();
            }
        }
        /// <summary>
        /// 实现维度接口
        /// </summary>
        public interface Implementor
        {
            void OperationImp();
        }
        /// <summary>
        /// 具体的实现维度
        /// </summary>
        public class ImplementorA : Implementor
        {
            public void OperationImp()
            {
                Console.WriteLine("implementor a operate");
            }
        }
    }

      4.总结:

        桥接模式将实现和抽象做了分离.我们可以理解为实际的系统中可能从多个角度进行分类,每一种分类都可能变化,那么桥接模式能分离这些不同的角度,让它们独立变化,减少耦合.

    五.命令模式

      1.概念:

        命令模式(Command),将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作.

      2.示例类图:

      3.示例代码:

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace DesignPatternsCore
    {
        /// <summary>
        /// 发起命令的类
        /// </summary>
        public class Invoker
        {
            //可以使用字典存储所有的命令
            private Dictionary<string, Command> allCommandsDic;
            public Invoker()
            {
                allCommandsDic = new Dictionary<string, Command>();
            }
            //注册命令
            public void RegistCommand(string commandName,Command command)
            {
                if (!allCommandsDic.ContainsKey(commandName))
                {
                    allCommandsDic.Add(commandName, command);
                }
                else
                {
                    Console.WriteLine("commandName repeated");
                }
            }
            //移除命令
            public void RemoveCommand(string commandName)
            {
                if (allCommandsDic.ContainsKey(commandName))
                {
                    allCommandsDic.Remove(commandName);
                }
            }
            //执行命令
            public void ExecuteCommand(string commandName)
            {
                if (allCommandsDic.ContainsKey(commandName))
                {
                    allCommandsDic[commandName].Execute();
                }
            }
        }
        /// <summary>
        /// 命令父类
        /// </summary>
        public class Command
        {
            protected Receiver receiver;
            public Command(Receiver receiver)
            {
                this.receiver = receiver;
            }
            public virtual void Execute() { }
        }
        /// <summary>
        /// 命令A
        /// </summary>
        public class CommandA : Command
        {
            public CommandA(Receiver receiver) : base(receiver)
            {
    
            }
            public override void Execute()
            {
                //调用接收者的相应方法
                receiver.ActionA();
            }
        }
        /// <summary>
        /// 命令B
        /// </summary>
        public class CommandB : Command
        {
            public CommandB(Receiver receiver) : base(receiver)
            {
    
            }
            public override void Execute()
            {
                //调用接收者的相应方法
                receiver.ActionB();
            }
        }
        /// <summary>
        /// 具体的执行者
        /// </summary>
        public class Receiver
        {
            public void ActionA()
            {
                Console.WriteLine("action a");
            }
            public void ActionB()
            {
                Console.WriteLine("action b");
            }
        }
    }

      4.总结:

        命令模式的重点在于使接收请求的一方和处理请求的一方解耦,相互之间不可知.具体的命令可以看作是请求的转交者,在转交请求时有时需要对传入的数据一并进行处理,这有一点MVC的味道.

        命令模式和观察者模式有一定的相似之处.命令模式的各种命令也可以使用多种方式存储(键值对或委托),命令不一定是一个类对象,也可以只是一个方法.命令模式重点在于对请求的转交,一条命令一般触发一个命令(也可以使用复合命令组合各种基本命令,可以视作执行了多个命令),观察者模式则是对象自身存储被观察者的引用,在自身发生特定改变后通知所有被观察者(调用被观察者的相应方法).

    六.职责链模式

      1.概念:

        职责链模式(Chain of Responsibility),使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止.

      2.示例类图:

      3.示例代码:

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace DesignPatternsCore
    {
        /// <summary>
        /// 职责链
        /// </summary>
        public class ChainOfResponsibility
        {
            //可以使用多种方式存储请求的处理者,使用数组List键值对或链式存储(保存下一个处理者对象的引用)等方式都可以
            //这里使用List
            private List<IHandler> allHandlerList;
            public ChainOfResponsibility()
            {
                allHandlerList = new List<IHandler>();
            }
            /// <summary>
            /// 添加处理者
            /// </summary>
            /// <param name="handler"></param>
            public void AddHandler(IHandler handler)
            {
                allHandlerList.Add(handler);
            }
            /// <summary>
            /// 移除处理者
            /// </summary>
            /// <param name="handler"></param>
            public void RemoveHandler(IHandler handler)
            {
                for (int i = 0; i < allHandlerList.Count; i++)
                {
                    if(allHandlerList[i] == handler)
                    {
                        allHandlerList.RemoveAt(i);
                        return;
                    }
                }
            }
            /// <summary>
            /// 处理请求
            /// </summary>
            /// <param name="requestParam"></param>
            /// <returns>请求是否得到处理</returns>
            public bool HandleRequest(int requestParam)
            {
                //遍历所有处理者,如果有一个处理者处理了请求,立即返回
                for(int i = 0;i < allHandlerList.Count; i++)
                {
                    if (allHandlerList[i].HandleRequest(requestParam))
                    {
                        return true; ;
                    }
                }
                return false;
            }
        }
        /// <summary>
        /// 请求处理者接口
        /// </summary>
        public interface IHandler
        {
            /// <summary>
            /// 处理实际请求的方法
            /// </summary>
            /// <param name="requestParam"></param>
            /// <returns>是否处理了此请求</returns>
            bool HandleRequest(int requestParam);
        }
        /// <summary>
        /// 实际请求处理者A
        /// </summary>
        public class HandlerA : IHandler
        {
            public bool HandleRequest(int requestParam)
            {
                if(requestParam > 10) 
                {
                    Console.WriteLine("handler a handle request");
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }
        /// <summary>
        /// 实际请求处理者B
        /// </summary>
        public class HandlerB : IHandler
        {
            public bool HandleRequest(int requestParam)
            {
                if (requestParam > 0 && requestParam <= 10)
                {
                    Console.WriteLine("handler b handle request");
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }
        /// <summary>
        /// 实际请求处理者C
        /// </summary>
        public class HandlerC : IHandler
        {
            public bool HandleRequest(int requestParam)
            {
                if (requestParam <= 0)
                {
                    Console.WriteLine("handler c handle request");
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }
    }

      4.总结

        职责链模式中,对于多个请求的处理者,可以使用一个合适的数据结构进行存储,如链式存储(链表)或线性存储(数组等).虽然这个模式名称是职责链,但是不是说所有请求的处理者一定要使用链式存储.在调用的过程中,遍历存储的所有处理者,如果有一个处理者成功处理了请求,就不再向下遍历.

        在通信的过程中,对于接收到的消息可以统一处理,也可以在不同的模块中分散处理(各自处理自己的消息).如果使用分散处理消息的方式就可以使用职责链模式.

    七.享元模式

      1.概念:

        享元模式(Flyweight),即运用共享技术有效地支持大量细粒度的对象.

      2.应用:

        对一个程序而言,可以将所有对象粗略分为外部状态和内部状态两类,如数据模块一般都是内部状态.享元模式就是共享元素或者说内部状态的共享,如数据的共享等.享元模式的一个重要应用就是各种池,如线程池对象池等.

  • 相关阅读:
    封装缓动动画函数
    封装动画函数-匀速运动
    实现产品图片的放大镜效果:
    仿淘宝侧边栏滚动案例:
    页面被卷去的头部兼容性解决方案
    简单发送短信倒计时案例
    Echarts 版本的那些坑
    json变量作键名
    媒体查询那些事儿
    mac 强制关闭指定端口
  • 原文地址:https://www.cnblogs.com/movin2333/p/15122001.html
Copyright © 2020-2023  润新知