zoukankan      html  css  js  c++  java
  • 设计模式学习笔记五:建造者模式装饰模式模板方法模式原型模式中介者模式代理模式外观模式适配器模式

    一.建造者模式

      1.概念:

        建造者模式(Builder),是将一个复杂对象的构建与它的表示分离,使同样的构建过程可以创建不同的表示.

      2.实现类图:

      3.代码示例(C#)

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace DesignPatternsCore
    {
        /// <summary>
        /// 指挥者,进行对象构建
        /// </summary>
        public class Director
        {
            /// <summary>
            /// 具体的构建方法
            /// </summary>
            public void Construct(IBuilder builder)
            {
                builder.BuildPart1();
                builder.BuildPart2();
                builder.BuildPart3();
                builder.BuildPart4();
    
            }
        }
        /// <summary>
        /// 建造者接口
        /// </summary>
        public interface IBuilder
        {
            void BuildPart1();
            void BuildPart2();
            void BuildPart3();
            void BuildPart4();
    
        }
        /// <summary>
        /// 具体建造者
        /// </summary>
        public class ConcreteBuilder : IBuilder
        {
            public void BuildPart1()
            {
                Console.WriteLine("build part 1");
            }
    
            public void BuildPart2()
            {
                Console.WriteLine("build part 2");
            }
    
            public void BuildPart3()
            {
                Console.WriteLine("build part 3");
            }
    
            public void BuildPart4()
            {
                Console.WriteLine("build part 4");
            }
        }
    }

      4.总结:建造者模式适用于那些建造过程比较固定但是建造过程又比较繁琐的对象构造,这样在常见新类型的对象模板时,就只需要集成对象的接口,实现其中具体的建造细节接口,在使用时指定建造类.但是如果建造过程经常改变,那么就需要修改所有的建造子类或者修改建造接口,违反了开闭原则.

    二.装饰模式

      1.概念

        装饰模式(Decorator),指动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活.

        在装饰模式中,装饰类会持有被装饰类的对象(一般在装饰类的构造方法中传入这个对象),对于被装饰类本来就有的功能,调用被装饰类对象的相应功能进行完成,除此以外,再开放一些新的拓展功能接口.

      2.示例类图

      3.示例代码

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace DesignPatternsCore
    {
        public interface IComponent
        {
            void DoSomething();
        }
        /// <summary>
        /// 装饰者
        /// 和被装饰者继承同样的接口,保证有相同的方法
        /// 可以继承这个装饰者创建装饰者子类拓展更多属性和方法
        /// </summary>
        public class Decorator : IComponent
        {
            //持有被装饰者的对象
            private ConcreteComponent component;
            //构造方法中传入被装饰者
            public Decorator(ConcreteComponent component)
            {
                this.component = component;
            }
            //被装饰者有的方法直接调用
            public void DoSomething()
            {
                component.DoSomething();
            }
            //拓展的方法
            public void DoMorething()
            {
                Console.WriteLine("do morething");
            }
        }
        /// <summary>
        /// 被装饰者
        /// </summary>
        public class ConcreteComponent : IComponent
        {
            public void DoSomething()
            {
                Console.WriteLine("do something");
            }
        }
    }

      4.总结:装饰者模式可以在不改动原有类的属性和功能的基础上为这个类拓展功能,甚至可以用装饰者的不同子类构造出不同的功能拓展模板.在设计的时候,可以使用装饰的方式将一个模块的核心功能和附加功能区分开,这样可以避免不小心更改了核心功能的情况出现.

    三.模板方法模式

      1.概念:

        模板方法模式(Template Method),其定义了一个操作中的算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤.

        可以理解为,模板方法模式定义了一系列的步骤,而这些步骤的实现交给子类去自己实现.如Unity中MonoBehaviour脚本的生命周期函数就可以视为使用了模板方法模式(虽然其基于反射实现,但是原理相同).

      2.示例类图:

      3.示例代码:

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace DesignPatternsCore
    {
        /// <summary>
        /// 模板方法
        /// </summary>
        public abstract class TemplateMethod
        {
            //构造函数中定义函数调用步骤
            public TemplateMethod()
            {
                OnInit();
                OnStart();
                OnShow();
            }
            //各种初始化函数
            protected abstract void OnInit();
            protected abstract void OnShow();
            protected abstract void OnStart();
        }
        /// <summary>
        /// 子类继承父类
        /// </summary>
        public class ConcreteClass : TemplateMethod
        {
            protected override void OnInit()
            {
                Console.WriteLine("on init");
            }
    
            protected override void OnShow()
            {
                Console.WriteLine("on show");
            }
    
            protected override void OnStart()
            {
                Console.WriteLine("on start");
            }
        }
    }

    四.原型模式

      1.概念:

        原型模式(Prototype):就是用原型示例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.

        原型模式和模板方法模式有很大区别.模板方法模式重在方法的模板,预先设计好方法的调用次序,实现细节交给子类完成;原型模式重在整个对象的原型(包含属性和方法),通过拷贝(深拷贝或浅拷贝)的方式创建新对象,再修改新对象和原对象的不同点,因此原型模式也叫做克隆(Clone)模式.

      2.实现:

        在.net的System命名空间中提供了ICloneable接口,实现原型模式只需要继承这个接口,并实现Clone()方法即可.如下图所示:

         MemberwiseClone方法是object对象提供的浅拷贝方法,如果需要深拷贝,还要自己实现.

     五.中介者模式

      1.概念:

        中介者模式(Mediator),指用一个中介对象来封装一系列的对象交互.中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变他们之间的交互.

        中介者模式是一个心状结构,中介者是核心,负责协调各对象之间的交互.中介者的优点在于协调个对象之间的交互,但是同时缺点也一样,中介者模式往往由于协调的对象交互过多,导致中介者过于复杂,维护困难.

      2.实现类图:

      3.实现代码:

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace DesignPatternsCore
    {
        /// <summary>
        /// 中介者
        /// </summary>
        public class Mediator
        {
            //需要了解所有的同事对象
            private List<Colleague> colleagueList;
    
            public Mediator()
            {
                colleagueList = new List<Colleague>();
            }
    
            public void AddColleague(Colleague colleague)
            {
                colleagueList.Add(colleague);
            }
    
            public void SendGift(Colleague colleague)
            {
                for(int i = 0;i < colleagueList.Count; i++)
                {
                    if(colleague != colleagueList[i])
                    {
                        colleagueList[i].ReceiveGift(colleague.Name);
                    }
                }
            }
        }
        /// <summary>
        /// 所有同事类的父类
        /// </summary>
        public class Colleague
        {
            //所有同事都必须了解中介者
            protected Mediator mediator;
            public string Name { get; protected set; }
    
            public Colleague(string name,Mediator mediator)
            {
                Name = name;
                this.mediator = mediator;
            }
            public virtual void SendGift()
            {
                mediator.SendGift(this);
            }
            public virtual void ReceiveGift(string senderName)
            {
                Console.WriteLine(Name + " have received gift from " + senderName);
            }
        }
        /// <summary>
        /// 同事A
        /// </summary>
        public class ColleagueA : Colleague
        {
            public ColleagueA(Mediator mediator) : base("ColleagueA",mediator)
            {
                mediator.AddColleague(this);
            }
    
        }
        /// <summary>
        /// 同事B
        /// </summary>
        public class ColleagueB : Colleague
        {
            public ColleagueB(Mediator mediator) : base("ColleagueB", mediator)
            {
                mediator.AddColleague(this);
            }
    
        }
        /// <summary>
        /// 同事C
        /// </summary>
        public class ColleagueC : Colleague
        {
            public ColleagueC(Mediator mediator) : base("ColleagueC", mediator)
            {
                mediator.AddColleague(this);
            }
    
        }
    }

    六.代理模式:

      1.概念:

        代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问.

      2.应用:

        代理模式很多时候和装饰者模式是混用的,两者的实现几乎相同,代理模式也会持有被代理对象的引用,并且和被代理对象继承自同样的接口或类.实际调用时直接调用被代理对象的功能.但是两种模式的侧重点不同,代理模式侧重于代理对象,即调用对象已有的功能,而装饰者模式侧重于拓展对象,即为对象添加新的功能.但是使用过程中可以不必区分得那么详细,符合实际需求即可.

        代理模式和中介者模式就有比较大的区别了.中介者模式是管理多个对象之间的相互调用,在中介者模式中中介者是核心;代理模式往往只代理单个对象的对外交互功能,在代理模式中被代理对象是核心.

    七.外观模式

      1.概念:

        外观模式(Facade),指为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用.

      2.应用:

        对于外观模式,同样没有做实现,因为其和代理模式中介模式同样非常相似.代理模式一般代理一个对象的对外交互,而外观模式一般代理多个对象的对外交互.外观模式的Facade类和中介者模式的Mediator类在实际应用中又经常整合到一个类中,因为这两者都是处理多个对象的相互交互或对外交互的问题,这两种职能在实际应用中往往难以区分,如使用中介者模式和外观模式的对象是一些玩家属性对象,提供一个获取单个对象总属性值的接口,这个接口就既可以是对外交互的接口,也可以是多个属性对象之间交互的接口.

    八.适配器模式

      1.概念:

        适配器模式(Adaptor),指将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的哪些类可以一起工作.

      2.应用:

        适配器模式很好理解,生活中常见适配器,如负责将220v的交流电转化为手机充电使用的直流电的电源适配器.在工程中也经常有使用适配器的地方,如Unity中热更代码和基础工程代码的相互调用就可以提供适配器进行转换.

        

  • 相关阅读:
    关于DRY原则
    类型之惑
    ThoughtWorks测试
    编程非易事
    瀑布与迭代的真实区别
    对TDD原则的理解
    自我练习
    C# CreateProcess的测试
    乱侃OOD
    复杂系统的五个属性
  • 原文地址:https://www.cnblogs.com/movin2333/p/15116475.html
Copyright © 2011-2022 走看看