1. 程式人生 > 其它 >設計模式學習筆記五:建造者模式\裝飾模式\模板方法模式\原型模式\中介者模式\代理模式\外觀模式\介面卡模式

設計模式學習筆記五:建造者模式\裝飾模式\模板方法模式\原型模式\中介者模式\代理模式\外觀模式\介面卡模式

一.建造者模式

  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中熱更程式碼和基礎工程程式碼的相互呼叫就可以提供介面卡進行轉換.