Head First 設計模式 C#實現(xiàn)

Head First 設計模式

[TOC]

完整源碼

GitHub倉庫

設計模式入門

  • 面向?qū)ο蠡A
    • 抽象
    • 封裝
    • 繼承
    • 多態(tài)
  • 良好的面向?qū)ο笤O計
    • 復用性
    • 擴充性
    • 可維護性
  • 面向?qū)ο笤瓌t
    • 封裝變化
    • 多用組合焚廊,少用繼承
    • 針對接口編程货邓,不針對實現(xiàn)編程
    • 為交互對象之間的松耦合努力
    • 開放閉合原則
      • 一個類對擴展開放祠锣,對修改關閉
      • 原先的main調(diào)用不受影響
    • 依賴倒置原則
      • 要依賴抽象口芍,不要依賴具體類
      • 高層組件和底層組件都應該依賴于抽象
    • 最少知識原則
      • 類之間的交流越簡單越好
    • 好萊塢原則
      • 高層依賴底層
      • 底層不依賴高層
    • 單一職責原則
      • 類的功能越單一越好

具體設計模式

策略模式

  • 定義算法族叨叙,分別封裝起來重付,讓他們之間可以互相替換玄组。讓算法的變化獨立于使用算法的客戶。(將變化部分封裝為成員變量胧辽,借用成員變量的多態(tài)實現(xiàn)方法的互換)

  • 具體實現(xiàn)

    • 實現(xiàn)場景:不同的鴨子具有不同的行為
    • 將行為抽象為接口
    • 將接口作為成員變量峻仇,行為類繼承行為接口
    • 實例鴨子類時指定特定行為類
      • 行為相當于算法,算法變化獨立于使用算法的用戶(鴨子)
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    ///策略模式:封裝變化為接口
    ///把成員方法轉化為成員屬性
    namespace StrategyPattern
    {
    public interface IFlyBehavior
    {
    void Fly();
    }

        public interface IQuackBehavior
        {
            void Quack();
        }

        public abstract class Duck
        {
            protected IFlyBehavior flyBehavior;
            protected IQuackBehavior quackBehavior;

            public Duck() { }

            public void PerformFly()
            {
                flyBehavior.Fly();
            }
            public void PerformQuack()
            {
                quackBehavior.Quack();
            }

            public virtual void Display()
            {
                PerformFly();
                PerformQuack();
                Siwm();
            }

            public void Siwm()
            {
                Console.WriteLine("游泳");
            }

            public void SetFlyBehavior(IFlyBehavior fly)
            {
                flyBehavior = fly;
            }

            public void SetQuackBehavior(IQuackBehavior quack)
            {
                quackBehavior = quack;
            }
        }

        public class FlyWithWings : IFlyBehavior
        {
            public void Fly()
            {
                Console.WriteLine("用翅膀飛");
            }
        }

        public class FlyNoWay : IFlyBehavior
        {
            public void Fly()
            {
                Console.WriteLine("不能飛");
            }
        }

        public class NormalQuack : IQuackBehavior
        {
            public void Quack()
            {
                Console.WriteLine("呱呱叫");
            }
        }
        public class MuteQuack : IQuackBehavior
        {
            public void Quack()
            {
                Console.WriteLine("不能叫");
            }
        }

        public class MallardDuck : Duck
        {
            public MallardDuck()
            {
                flyBehavior = new FlyWithWings();
                quackBehavior = new NormalQuack();
            }

            public override void Display()
            {
                Console.WriteLine("我是一只綠頭鴨");
                base.Display();
            }
        }

        public class ModelDuck : Duck
        {
            public ModelDuck()
            {
                flyBehavior = new FlyNoWay();
                quackBehavior = new MuteQuack();
            }
            public override void Display()
            {
                Console.WriteLine("我是一只模型鴨");
                base.Display();
            }
        }

        class StrategyPatternMain
        {
            public void Main()
            {
                MallardDuck mallardDuck = new MallardDuck();
                ModelDuck modelDuck = new ModelDuck();
                mallardDuck.Display();
                modelDuck.Display();
                Console.WriteLine("綠頭鴨摔斷了翅膀");
                mallardDuck.SetFlyBehavior(new FlyNoWay());
                mallardDuck.Display();
            }
        }

    }

觀察者模式

  • 在對象之間定義一對多的關系邑商,當主對象改變時摄咆,所有依賴其的對象收到通知凡蚜,自動更新

  • 具體實現(xiàn)

    • 主題接口維護一個觀察者列表
    • 給所有觀察者發(fā)送消息(調(diào)用觀察者方法)
      • 主題通過參數(shù)推數(shù)據(jù)
      • 觀察者通過參數(shù)拉數(shù)據(jù)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PatternDesign;

namespace ObserverPattern
{
    /// <summary>
    /// 主題
    /// 添加監(jiān)聽者
    /// 刪除監(jiān)聽者
    /// </summary>
    public interface ISubject
    {
        bool isChange { get; set; }
        List<IObserver> obervers { get; set; }

        void AddObserver(IObserver oberver);
        void RemoveObserver(IObserver oberver);

        void SetChange(ISubject subject);
        void NotifyObservers();
    }

    public interface IObserver
    {
        void Update(ISubject subject);
    }

    public class WeatherData : ISubject
    {

        public string Name { get; set; }
        public string Description { get; set; }

        public bool isChange { get; set; }

        public WeatherData()
        {
            Name = "天氣數(shù)據(jù)";
            Description = "今天氣溫25度";

            isChange = false;
            obervers = new List<IObserver>();
        }

        public List<IObserver> obervers { get; set; }

        public void AddObserver(IObserver oberver)
        {
            obervers.Add(oberver);
        }

        public void RemoveObserver(IObserver oberver)
        {
            obervers.Remove(oberver);
        }
        public void SetChange(ISubject subject)
        {
            isChange = true;
            NotifyObservers();
        }

        public void NotifyObservers()
        {
            if (isChange)
            {
                foreach (IObserver oberver in obervers)
                {
                    oberver.Update(this);
                }
                isChange = false;
            }
        }


    }

    public class Display1 : IObserver
    {
        public void Update(ISubject subject)
        {
            WeatherData weatherData = (WeatherData)subject;
            Console.WriteLine("展示牌一:");
            Console.WriteLine(weatherData.Name);
            Console.WriteLine(weatherData.Description);
        }
    }

    public class Display2 : IObserver
    {
        public void Update(ISubject subject)
        {
            WeatherData weatherData = (WeatherData)subject;
            Console.WriteLine("展示牌二:");
            Console.WriteLine(weatherData.Name);
            Console.WriteLine(weatherData.Description);
        }
    }

    public class Display3 : IObserver
    {
        public void Update(ISubject subject)
        {
            WeatherData weatherData = (WeatherData)subject;
            Console.WriteLine("展示牌三:");
            Console.WriteLine(weatherData.Name);
            Console.WriteLine(weatherData.Description);
        }
    }

    public class WeatherDataByS : IObservable<WeatherDataByS>, IDisposable
    {
        List<IObserver<WeatherDataByS>> observers;

        public WeatherDataByS()
        {
            observers = new List<IObserver<WeatherDataByS>>();
        }

        public IDisposable Subscribe(IObserver<WeatherDataByS> observer)
        {
            observers.Add(observer);
            return this;
        }

        public void NotifyObservers()
        {

            foreach (IObserver<WeatherDataByS> observer in observers)
            {
                observer.OnNext(this);
                observer.OnCompleted();
            }
        }

        public void Dispose()
        {
            Console.WriteLine("通知公告板");
        }
    }

    public class DisplayByS1 : IObserver<WeatherDataByS>
    {
        public void OnNext(WeatherDataByS value)
        {
            value.Dispose();
        }

        public void OnError(Exception error)
        {
            error.ToString();
        }

        public void OnCompleted()
        {
            Console.WriteLine("通知完成");
        }
    }


    internal class ObserverPatternMain : IPattern
    {
        public void Main()
        {
            ISubject weatherData = new WeatherData();

            IObserver display1 = new Display1();
            IObserver display2 = new Display2();
            IObserver display3 = new Display3();

            weatherData.AddObserver(display1);
            weatherData.AddObserver(display2);
            weatherData.AddObserver(display3);

            weatherData.SetChange(weatherData);


            IObservable<WeatherDataByS> observable = new WeatherDataByS();
            IObserver<WeatherDataByS> observer = new DisplayByS1();

            observable.Subscribe(observer);
            ((WeatherDataByS)observable).NotifyObservers();
        }
    }
}

裝飾者模式

  • 動態(tài)的將責任附加到對象上。有別于繼承的擴展功能吭从。
  • 組件朝蜘,裝飾器
    • 組件(被裝飾者)和裝飾器是同一類型
    • 裝飾器可以以一定順序添加或替換組件方法(拓展/改變)
      • 裝飾器內(nèi)部有組件變量
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PatternDesign;

namespace DecoratorPattern
{
    /// <summary>
    /// 裝飾器模式
    /// 組件和裝飾器
    /// </summary>

    public interface IFood
    {
        string Name { get; }
        string Description { get; set; }

        string GetDescription();
        double Cost();
    }

    /// <summary>
    /// 被裝飾食物接口
    /// </summary>
    public abstract class AbstractFood : IFood
    {
        public string Name { get; }

        public string Description { get; set; }

        public virtual string GetDescription()
        {
            return Description;
        }

        abstract public double Cost();
    }

    /// <summary>
    /// 抽象調(diào)料裝飾器
    /// </summary>
    public abstract class CondimentDecorator : AbstractFood
    {
        protected IFood food;
        public abstract override string GetDescription();
    }

    public class Hamburger : AbstractFood
    {
        public Hamburger()
        {
            Description = "漢堡包";
        }
        public override double Cost()
        {
            return 1;
        }
    }


    public class Salt : CondimentDecorator
    {
        public Salt(IFood food)
        {
            this.food = food;
        }
        public override string GetDescription()
        {
            return food.GetDescription() + "加鹽";
        }

        public override double Cost()
        {
            return food.Cost() + 0.1f;
        }
    }

    public class Suger : CondimentDecorator
    {
        public Suger(IFood food)
        {
            this.food = food;
        }
        public override string GetDescription()
        {
            return food.GetDescription() + "加糖";
        }

        public override double Cost()
        {
            return food.Cost() + 0.2f;
        }
    }



    internal class DecoratorPatternMain : IPattern
    {

        public void Main()
        {

            IFood hamburger = new Hamburger();
            hamburger = new Salt(hamburger);
            hamburger = new Suger(hamburger);
            hamburger = new Salt(hamburger);

            Console.WriteLine(hamburger.GetDescription());

        }
    }
}

工廠模式

  • 定義
    • 定義了一個創(chuàng)建對象的接口,但由子類決定要實例化的類是哪一個影锈。工廠方法讓類把實例化延遲到子類
  • 解決問題
    • 將客戶程序從具體類解耦
  • 實現(xiàn)思路
    • 抽象產(chǎn)品
      • 具體產(chǎn)品繼承抽象產(chǎn)品接口
        • 通過產(chǎn)品接口與具體類型產(chǎn)品解耦,從而生產(chǎn)不同類型產(chǎn)品
    • 創(chuàng)建者
      • 創(chuàng)建抽象產(chǎn)品的接口
        • 具體創(chuàng)建者實現(xiàn)創(chuàng)建接口
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FactoryPattern
{
    abstract class Creator
    {
        abstract public Product FactoryMethod(string type);
    }

    abstract class Product
    {
        protected string Name;
        protected string Description;
        public abstract void Display();
    }

    class LittelHamburger : Product
    {
        public LittelHamburger()
        {
            Name = "小漢堡";
            Description = "這是一個小漢堡";
        }
        public override void Display()
        {
            Console.WriteLine(Name + " " + Description);
        }
    }

    class BigHamburger : Product
    {
        public BigHamburger()
        {
            Name = "大漢堡";
            Description = "這是一個大漢堡";
        }
        public override void Display()
        {
            Console.WriteLine(Name + " " + Description);
        }
    }

    class HamburgerCreator : Creator
    {
        public override Product FactoryMethod(string type)
        {
            switch (type)
            {
                case "大漢堡":
                    return new BigHamburger();
                case "小漢堡":
                    return new LittelHamburger();
                default:
                    return null;
            }
        }
    }

    internal class FactoryPatternMain : IPattern
    {


        public void Main()
        {
            Creator creator = new HamburgerCreator();
            Product product = creator.FactoryMethod("大漢堡");
            Product product1 = creator.FactoryMethod("小漢堡");

            product.Display();
            product1.Display();
        }
    }
}

抽象工廠模式

  • 提供一個接口蝉绷,用于創(chuàng)建相關或依賴對象家族鸭廷,而不需要明確指定具體類
    • 客戶要一個產(chǎn)品,描述一個必要的概念即可或得一個復雜產(chǎn)品熔吗,復雜產(chǎn)品生產(chǎn)過程封裝在工廠中辆床,抽象工廠模式可以在不改變用戶點餐方式,給工廠加復雜度
    • 工廠模式+策略模式
  • 抽象工廠與工廠的區(qū)別
    • 工廠模式使用繼承桅狠,將具體對象的創(chuàng)建延遲給子類實現(xiàn)
    • 抽象工廠使用組合讼载,將具體對象的創(chuàng)建被組合的工廠子類實現(xiàn)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AbstractFactoryPattern
{
    /// <summary>
    /// 抽象工廠模式
    /// 工廠模式+策略模式
    /// </summary>

    abstract class Creator
    {
        /// <summary>
        /// 工廠方法
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        abstract public Product FactoryMethod(string type);
    }

    /// <summary>
    /// 調(diào)料工廠采用組合方式
    /// </summary>
    abstract class IngredientCreator
    {
        /// <summary>
        /// 工廠方法
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        abstract public string CreateSalt();
        abstract public string CreateSuger();
    }

    /// <summary>
    /// 加了調(diào)料的復雜產(chǎn)品
    /// </summary>
    abstract class Product
    {
        protected string Salt;
        protected string Suger;

        protected string Name;
        protected string Description;

        //組合一個調(diào)料工廠
        protected IngredientCreator ingredientCreator;

        public abstract void Display();
    }

    class SugerIngredient : IngredientCreator
    {
        public override string CreateSalt()
        {
            return "不加鹽";
        }

        public override string CreateSuger()
        {
            return "加糖";
        }
    }
    class SaltIngredient : IngredientCreator
    {
        public override string CreateSalt()
        {
            return "加鹽";
        }

        public override string CreateSuger()
        {
            return "不加糖";
        }
    }

    class LittelHamburger : Product
    {
        public LittelHamburger(IngredientCreator ingredient)
        {
            Name = "小漢堡";
            Description = "這是一個小漢堡";
            this.ingredientCreator = ingredient;
            Salt = ingredientCreator.CreateSalt();
            Suger = ingredientCreator.CreateSuger();
        }

        public LittelHamburger()
        {
            Name = "小漢堡";
            Description = "這是一個小漢堡";
        }
        public override void Display()
        {
            Console.WriteLine(Name + " " + Description);
            Console.WriteLine(Salt);
            Console.WriteLine(Suger);
        }
    }

    class BigHamburger : Product
    {
        public BigHamburger(IngredientCreator ingredient)
        {
            Name = "大漢堡";
            Description = "這是一個大漢堡";
            this.ingredientCreator = ingredient;
            Salt = ingredientCreator.CreateSalt();
            Suger = ingredientCreator.CreateSuger();
        }

        public BigHamburger()
        {
            Name = "大漢堡";
            Description = "這是一個大漢堡";
        }
        public override void Display()
        {

            Console.WriteLine(Name + " " + Description);
            Console.WriteLine(Salt);
            Console.WriteLine(Suger);
        }
    }

    class HamburgerCreator : Creator
    {
        public override Product FactoryMethod(string type)
        {
            switch (type)
            {
                case "大漢堡":
                    return new BigHamburger();
                case "小漢堡":
                    return new LittelHamburger();
                case "甜大漢堡":
                    return new BigHamburger(new SugerIngredient());
                case "咸小漢堡":
                    return new LittelHamburger(new SaltIngredient());
                case "咸大漢堡":
                    return new BigHamburger(new SaltIngredient());
                case "甜小漢堡":
                    return new LittelHamburger(new SugerIngredient());
                default:
                    return null;
            }
        }
    }

    internal class AbstractFactoryPatternMain : IPattern
    {
        public void Main()
        {
            Creator creator = new HamburgerCreator();
            Product product = creator.FactoryMethod("大漢堡");
            Product product1 = creator.FactoryMethod("小漢堡");
            Product product2 = creator.FactoryMethod("甜大漢堡");
            Product product3 = creator.FactoryMethod("甜小漢堡");
            Product product4 = creator.FactoryMethod("咸大漢堡");
            Product product5 = creator.FactoryMethod("咸小漢堡");

            product.Display();
            product1.Display();
            product2.Display();
            product3.Display();
            product4.Display();
            product5.Display();
        }
    }
}

單例模式

  • 定義
    • 確保一個類只有一個實例,并提供全局訪問點中跌,延遲實例化
  • 解決問題
    • 保證只有一個實例
    • 提供全局訪問點咨堤,方便訪問
  • 實現(xiàn)思路
    • 簡單單例
      * 私有靜態(tài)屬性
      * 私有構造器
      * 公有靜態(tài)全局訪問點
      * 延遲實例化
    • 線程安全單例
      • 靜態(tài)構造器保證線程安全
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    namespace SingletonPattern
    {
    public class Singleton
    {
    private static Singleton instance;
    private Singleton() { }
    public static Singleton Instance
    {
    get
    {
    if (instance == null)
    {
    instance = new Singleton();
    }
    return instance;
    }
    }

            public void Display()
            {
                Console.WriteLine("我是簡單單例");
            }

        }

        /// <summary>
        /// 完全懶漢多線程安全單例模式
        /// </summary>
        public sealed class SyncSingleton
        {
            private SyncSingleton() { }
            public static SyncSingleton Instance { get { return Nested.instance; } }
            private class Nested
            {
                //Explicit static constructor to tell C# compiler
                //not to mark type as beforefieldinit
                static Nested()
                {
                }
                internal static readonly SyncSingleton instance = new SyncSingleton();
            }
            public void Display()
            {
                Console.WriteLine("這是一個線程安全的單例模式");
            }
        }

        internal class SingletonPatternMain : IPattern
        {
            public void Main()
            {
                Singleton.Instance.Display();
                SyncSingleton.Instance.Display();
            }
        }

    }

命令模式

  • 定義
    • 將請求封裝成對象,使用不同的請求來參數(shù)化其他對象的命令
  • 解決的問題
    • 將請求者與執(zhí)行者之間解耦(運行時靈活指定)
    • 支持撤銷操作
    • 支持宏命令
    • 可實現(xiàn)日志和事物系統(tǒng)
  • 實現(xiàn)思路
    • 請求者
      • 命令
      • 設置命令方法
    • 命令
      • 執(zhí)行者
      • 執(zhí)行方法漩符,撤銷方法...
    • 執(zhí)行者
      • 提供相關功能的接口
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CommandPattern
{
    /// <summary>
    /// 命令模式
    /// 請求者
    /// 命令
    /// 執(zhí)行者
    /// </summary>

    interface IInvoker
    {
        void SetCommand(ICommand command);
        void SetCommand(ICommand[] commands);
        void ExecuteCommand();
        void ExecuteCommands();
    }

    abstract class Invoker : IInvoker
    {
        protected ICommand command;
        protected ICommand[] commands;

        public abstract void SetCommand(ICommand command);
        public abstract void SetCommand(ICommand[] commands);
        public abstract void ExecuteCommand();
        public abstract void ExecuteCommands();
    }

    interface ICommand
    {
        void Execute();
        void Undo();
    }

    abstract class Command : ICommand
    {
        public IReceiver receiver { set; get; }

        public Command(IReceiver receiver)
        {
            this.receiver = receiver;
        }

        public virtual void Execute()
        {
            receiver.DoSomething();
        }

        public virtual void Undo()
        {
            receiver.UndoSomething();
        }
    }

    interface IReceiver
    {
        void DoSomething();
        void UndoSomething();
    }

    class Ligtht : IReceiver
    {
        public void DoSomething()
        {
            Console.WriteLine("開燈");
        }

        public void UndoSomething()
        {
            Console.WriteLine("關燈");
        }
    }

    class RemoteControl : Invoker
    {
        protected ICommand command;
        protected ICommand[] commands;

        public override void SetCommand(ICommand command)
        {
            this.command = command;
        }

        public override void SetCommand(ICommand[] commands)
        {
            this.commands = commands;
        }

        public override void ExecuteCommand()
        {
            command.Execute();
        }

        public override void ExecuteCommands()
        {
            foreach (var item in commands)
            {
                item.Execute();
            }
        }
    }


    class LightOnCommand : Command
    {
        public LightOnCommand(IReceiver receiver) : base(receiver)
        {
        }
    }

    class LitghtOffCommand : Command
    {
        public LitghtOffCommand(IReceiver receiver) : base(receiver)
        {
        }
    }

    internal class CommandPatternMain : IPattern
    {
        public void Main()
        {
            IInvoker remoteControl = new RemoteControl();
            IReceiver light = new Ligtht();
            LightOnCommand lightOnCommand = new LightOnCommand(light);
            LitghtOffCommand litghtOffCommand = new LitghtOffCommand(light);


            remoteControl.SetCommand(lightOnCommand);
            remoteControl.ExecuteCommand();
            remoteControl.SetCommand(litghtOffCommand);
            remoteControl.ExecuteCommand();

        }
    }
}

適配器模式

  • 定義
    • 將一個類的接口一喘,轉換成客戶期望的另一個接口。
  • 解決問題
    • 讓客戶從實現(xiàn)的接口解耦
  • 實現(xiàn)思路
    • 適配器:實現(xiàn)目標接口
      • 組合被適配者
      • 使用被適配者方法實現(xiàn)目標接口方法
    • 被適配者
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AdapterPattern
{
    /// <summary>
    /// 適配器
    /// 目標
    /// 被適配器
    /// </summary>

    interface Target
    {
        void TDoSomething();
    }

    class Adaptee
    {
        public void ADoSomething()
        {
            Console.WriteLine("適配者再做");
        }
    }

    class Adapter : Target
    {
        Adaptee adaptee;
        public Adapter(Adaptee adaptee)
        {
            this.adaptee = adaptee;
        }

        public void TDoSomething()
        {
            adaptee.ADoSomething();
        }
    }



    internal class AdapterPatternMain : IPattern
    {
        public void Main()
        {
            Adaptee adaptee = new Adaptee();
            Adapter adapter = new Adapter(adaptee);
            adapter.TDoSomething();
        }
    }
}

外觀模式

  • 定義
    • 提供一個統(tǒng)一的接口來訪問子系統(tǒng)中的一群接口嗜暴。定義了一個高層接口讓子系統(tǒng)更容易使用
  • 解決問題
    • 將客戶從一個復雜子系統(tǒng)中解耦
    • 簡化接口
  • 實現(xiàn)思路
    • 外觀類(總系統(tǒng))
      • 組合各種子系統(tǒng)
      • 提供方便調(diào)用(簡化)的接口
        • 具體功能由子系統(tǒng)實現(xiàn)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FacadePattern
{
    class Facada
    {
        public Func1 func1;
        public Func2 func2;
        public Facada(Func1 func1, Func2 func2)
        {
            this.func1 = func1;
            this.func2 = func2;
        }

        public void Do()
        {
            func1.Do();
            func2.Do();
        }
    }

    class Func1
    {
        public void Do()
        {
            Console.WriteLine("func1 do");
        }
    }

    class Func2
    {
        public void Do()
        {
            Console.WriteLine("func2 do");
        }
    }

    internal class FacadePatternMain : IPattern
    {
        public void Main()
        {
            Func1 func1 = new Func1(); ;
            Func2 func2 = new Func2();
            Facada facada = new Facada(func1, func2);
            facada.Do();
        }
    }
}

模版方法模式

  • 定義
    • 在一個方法中定義一個算法的骨架凸克,而將一些步驟延遲到子類中。
  • 解決問題
    • 提高代碼復用的重要技巧
    • 鉤子方法(超類固定調(diào)用的事件函數(shù))
      • 影響模版方法的調(diào)用
  • 實現(xiàn)思路
    • 超類
      • 定義算法模型
        • 以實現(xiàn)的方法
          • 可由子類重寫
        • 未實現(xiàn)的方法(抽象方法)
          • 由子類實現(xiàn)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TemplatePattern
{
    abstract class CaffeeineBeverageWithHook
    {
        /// <summary>
        /// 模版方法
        /// </summary>
        public void PrepareRecipe()
        {
            BoilWater();
            Brew();
            PourInCup();
            if (IsNeedAddCondiments())
            {
                AddCondiments();
            }
        }

        protected void BoilWater()
        {
            Console.WriteLine("水煮開了");
        }
        abstract protected void Brew();
        protected void PourInCup()
        {
            Console.WriteLine("倒進杯子里");
        }

        abstract protected void AddCondiments();

        virtual protected bool IsNeedAddCondiments()
        {
            return true;
        }

    }

    class Coffee : CaffeeineBeverageWithHook
    {
        protected override void Brew()
        {
            Console.WriteLine("泡咖啡");
        }

        protected override void AddCondiments()
        {
            Console.WriteLine("加奶");
        }
    }

    class Tea : CaffeeineBeverageWithHook
    {
        protected override void Brew()
        {
            Console.WriteLine("泡茶");
        }

        protected override void AddCondiments()
        {
            Console.WriteLine("不加調(diào)料闷沥,你應該看不見這句");
        }
        protected override bool IsNeedAddCondiments()
        {
            return false;
        }

    }

    internal class TemplatePatternMain : IPattern
    {
        public void Main()
        {
            CaffeeineBeverageWithHook coffee = new Coffee();
            CaffeeineBeverageWithHook tea = new Tea();

            coffee.PrepareRecipe();
            tea.PrepareRecipe();

        }
    }
}

迭代器模式

  • 定義
    • 提供一種方法順序訪問一個聚合對象中的各個元素萎战,而不暴露其內(nèi)部的表示
    • 遍歷方法的適配器模式
  • 解決問題
    • 解決具體集合與遍歷方法的耦合問題
  • 實現(xiàn)思路
    • 迭代器接口
      • 迭代對象集合
      • 索引值
      • 實現(xiàn)迭代器接口方法
    • 可被迭代器遍歷接口
      • 創(chuàng)建對應的迭代器(工廠模式)
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IteratorPattern
{
    interface IIterator
    {
        bool HasNext();
        object Next();
    }

    interface IAggregate
    {
        IIterator CreateIterator();
    }

    class ListIterator<T> : IIterator
    {
        List<T> list;
        int index = 0;
        public ListIterator(List<T> list)
        {
            this.list = list;
        }

        public bool HasNext()
        {
            if (list == null || index >= list.Count)
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        public object Next()
        {
            return list[index++];
        }
    }

    class ArrayIterator<T> : IIterator
    {
        T[] list;
        int index = 0;

        public ArrayIterator(T[] list)
        {
            this.list = list;
        }

        public bool HasNext()
        {
            if (list == null || index >= list.Length)
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        public object Next()
        {
            return list[index++];
        }
    }

    class ListMenu : IAggregate
    {
        List<int> list;
        public ListMenu()
        {
            list = new List<int>();
            list.Add(0);
            list.Add(1);
            list.Add(2);
            list.Add(3);
        }

        public IIterator CreateIterator()
        {
            return new ListIterator<int>(list);
        }
    }

    class ArrayMenu : IAggregate
    {
        int[] list;
        public ArrayMenu()
        {
            list = new int[4];
            list[0] = 0;
            list[1] = 1;
            list[2] = 2;
            list[3] = 3;
        }

        public IIterator CreateIterator()
        {
            return new ArrayIterator<int>(list);
        }
    }

    internal class IteratorPatternMain : IPattern
    {
        public void Main()
        {
            IAggregate a = new ListMenu();
            IAggregate b = new ArrayMenu();
            foreachByIterator(a);
            foreachByIterator(b);

        }
        void foreachByIterator(IAggregate list)
        {
            IIterator aIterator = list.CreateIterator();
            while (aIterator.HasNext())
            {
                Console.WriteLine(aIterator.Next());
            }
        }

    }
}

組合模式

  • 定義
    • 允許將對象組成樹形結構來表現(xiàn)“整體/部分”的層次結構。組合能讓客戶以一致的方式處理個別對象和對象組合
    • 樹形結構存儲葉子節(jié)點和根節(jié)點
      • 葉子節(jié)點和根節(jié)點實現(xiàn)同一個接口
        • 實現(xiàn)的方法不同
  • 解決問題
    • 樹形結構舆逃,無視葉子節(jié)點與根節(jié)點區(qū)別蚂维,拓展性很強
  • 實現(xiàn)思路
    • 抽象組合類
      • 根節(jié)點使用的方法
      • 葉子節(jié)點使用的方法
      • 遍歷方法
    • 組合葉子節(jié)點繼承抽象組合
    • 組合根節(jié)點繼承抽象組合
  • 拓展
    • 組合迭代器
      • 棧,遞歸混用
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
using IteratorPattern;

namespace CompositePattern
{
    public abstract class Component
    {
        public virtual void Add(Component component)
        {
            throw new NotImplementedException();
        }
        public virtual void Remove(Component component)
        {
            throw new NotImplementedException();
        }
        public virtual Component GetChild(int i)
        {
            throw new NotImplementedException();
        }

        public virtual string GetName()
        {
            throw new NotImplementedException();
        }

        public virtual string GetDescription()
        {
            throw new NotImplementedException();
        }

        public virtual bool IsTarget()
        {
            throw new NotImplementedException();
        }
        public virtual void Print()
        {
            throw new NotImplementedException();
        }
    }

    public class ComponentItem : Component
    {
        string name;
        string description;
        bool isTarget;

        public ComponentItem(string name, string description, bool isTarget)
        {
            this.name = name;
            this.description = description;
            this.isTarget = isTarget;
        }

        public override string GetName()
        {
            return name;
        }

        public override string GetDescription()
        {
            return description;
        }

        public override bool IsTarget()
        {
            return isTarget;
        }

        public override void Print()
        {
            Console.WriteLine(GetName());
            Console.WriteLine(GetDescription());
            if (isTarget)
                Console.WriteLine("我是目標");
        }
    }

    public class ComponentMenu : Component, IAggregate
    {
        string name;
        string description;
        List<Component> components = new List<Component>();

        public ComponentMenu(string name, string description)
        {
            this.name = name;
            this.description = description;
        }

        public override void Add(Component component)
        {
            components.Add(component);
        }
        public override void Remove(Component component)
        {
            components.Remove(component);
        }
        public override Component GetChild(int i)
        {
            return components[i];
        }
        public override string GetName()
        {
            return name;
        }

        public override string GetDescription()
        {
            return description;
        }

        /// <summary>
        /// 樹形后根遍歷路狮,遞歸打印所有子節(jié)點
        /// </summary>
        public override void Print()
        {
            //打印自己
            Console.WriteLine(GetName());
            Console.WriteLine(GetDescription());
            //如果有子節(jié)點打印子節(jié)點
            //for (int i = 0; i < components.Count; i++)
            //{
            //    GetChild(i).Print();
            //}
            //使用迭代器遍歷
            IIterator iterator = CreateIterator();
            while (iterator.HasNext())
            {
                ((Component)iterator.Next()).Print();
            }
        }

        public void PrintTarget()
        {
            //使用迭代器遍歷
            IIterator iterator = CreateIterator();
            while (iterator.HasNext())
            {
                Component component = (Component)iterator.Next();
                try
                {
                    if (component.IsTarget())
                        component.Print();
                }
                catch (NotImplementedException)
                {
                    //Console.WriteLine("遍歷到菜單");
                    //component.Print();
                }
            }
        }

        public IIterator CreateIterator()
        {
            return new CompositeIterator(new ListIterator<Component>(components));
        }
    }

    /// <summary>
    /// 組合迭代器
    /// 組合一個數(shù)組迭代器鸟雏,利用棧,遍歷樹形結構
    /// </summary>
    public class CompositeIterator : IIterator
    {
        Stack stack = new Stack();
        public CompositeIterator(IIterator iterator)
        {
            stack.Push(iterator);
        }

        public bool HasNext()
        {
            if (stack.Count == 0)
            {
                return false;
            }
            else
            {
                IIterator iterator = (IIterator)stack.Peek();
                if (!iterator.HasNext())
                {
                    stack.Pop();
                    return HasNext();
                }
                else
                {
                    return true;
                }
            }
        }

        public object Next()
        {
            if (HasNext())
            {
                IIterator iterator = (IIterator)stack.Peek();
                Component component = (Component)iterator.Next();
                if (component is ComponentMenu)
                {
                    stack.Push(((ComponentMenu)component).CreateIterator());
                }
                return component;
            }
            else
            {
                return null;
            }
        }
    }

    internal class CompositePatternMain : IPattern
    {
        public void Main()
        {
            Component mainComponent = new ComponentMenu("主組件", "所有組件根節(jié)點");
            Component Component1 = new ComponentMenu("1組件", "主組件1號節(jié)點");
            Component Component2 = new ComponentMenu("2組件", "主組件2號節(jié)點");
            Component Component3 = new ComponentMenu("3組件", "主組件3號節(jié)點");
            Component Component11 = new ComponentMenu("1.1組件", "1號組件1號節(jié)點組件");

            mainComponent.Add(Component1);
            mainComponent.Add(Component2);
            mainComponent.Add(Component3);
            Component1.Add(Component11);

            Component item1 = new ComponentItem("1葉子", "一號組件的葉子1", true);
            Component item2 = new ComponentItem("2葉子", "二號組件的葉子1", true);
            Component item3 = new ComponentItem("3葉子", "三號組件的葉子1", true);
            Component item4 = new ComponentItem("4葉子", "1號組件1號節(jié)點組件的葉子1", true);
            Component item5 = new ComponentItem("5葉子", "1號組件1號節(jié)點組件的葉子2", true);

            Component1.Add(item1);
            Component2.Add(item2);
            Component3.Add(item3);
            Component11.Add(item4);
            Component11.Add(item5);

            //mainComponent.Print();
            ((ComponentMenu)mainComponent).PrintTarget();//二級菜單會被遍歷兩次

            Console.ReadLine();

        }
    }
}

狀態(tài)模式

  • 定義
    • 允許對象在內(nèi)部狀改變時改變他的行為览祖,對象看起來好像修改了它的類
  • 解決問題
    • 封裝不同狀態(tài)的行為孝鹊,易于拓展新功能
  • 實現(xiàn)
    • 上下文類
      • 內(nèi)部狀態(tài)類
      • 自己的方法
      • 委托給狀態(tài)類處理的方法
    • 抽象狀態(tài)類
      • 上下文類
      • 被委托的方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace StatePattern
{
    abstract class State
    {
        public abstract void Start();

        public abstract void End();
    }

    class Context
    {
        public State beginState;
        public State endState;

        State state;

        public Context()
        {
            beginState = new BeginState(this);
            endState = new EndState(this);

            state = beginState;
        }

        public void SetState(State state)
        {
            this.state = state;
        }

        public void Start()
        {
            state.Start();
        }

        public void End()
        {
            state.End();
        }

    }



    class BeginState : State
    {

        Context context;
        public BeginState(Context context)
        {
            this.context = context;
        }
        public override void Start()
        {
            Console.WriteLine("開始了");
            context.SetState(context.endState);
        }

        public override void End()
        {
            throw new NotImplementedException();
        }
    }

    class EndState : State
    {
        Context context;
        public EndState(Context context)
        {
            this.context = context;
        }

        public override void Start()
        {
            throw new NotImplementedException();
        }

        public override void End()
        {
            Console.WriteLine("結束了");
            context.SetState(context.beginState);
        }
    }


    internal class StatePatternMain : IPattern
    {
        public void Main()
        {
            Context context = new Context();
            context.Start();
            context.End();
        }
    }
}

代理模式

  • 定義
    • 為另一個對象提供一個替身或者占位符以訪問這個對象
  • 解決問題
    • 方便控制客戶對對象的訪問
      • 遠程代理
        • 控制和遠程對象的交互
      • 虛擬代理
        • 控制和實例化開銷大的對象的交互
      • 保護代理
        • 實現(xiàn)控制權限訪問對象
    • 反射機制
  • 實現(xiàn)
    • 類似裝飾者
    • 語言內(nèi)置代理

復合模式(MVC為例)

  • 定義
    • 結合兩個或以上的模式,組成一個解決方案解決問題
  • 解決問題
    • 大部分軟件開發(fā)需求無非就是輸入輸出
    • MVC模式將軟件開發(fā)分為三層
      • Model層實現(xiàn)應用邏輯展蒂,響應動作
      • Contoller層又活,將Model和View解耦苔咪,根據(jù)具體用戶需求訪問Model
      • View層,用戶交互
  • 實現(xiàn)思路
    • View
      • 組合模式
        • 組合控件
      • 策略模式
        • 組合控制器(和MOdel)
    • 控制器
      • 中介模式
      • 策略模式
        • 模型
        • View
    • Model
      • 觀察者模式

備忘錄模式

  • 定義
    • 在不破壞封裝性的前提下柳骄,捕獲一個對象的內(nèi)部狀態(tài)团赏,并在該對象之外保存這個狀態(tài)。
  • 解決問題
    • 所謂備忘錄模式就是在不破壞封裝的前提下耐薯,捕獲一個對象的內(nèi)部狀態(tài)舔清,并在該對象之外保存這個狀態(tài),這樣可以在以后將對象恢復到原先保存的狀態(tài)曲初。
  • 情景
    • 打游戲時的存檔体谒,版本管理
    • 回退功能
  • 實現(xiàn)思路
    • 類設計
      • 備忘錄類
      • CareTaker存儲備忘錄類
      • Originator管理備忘錄類
    • 使用
      • 通過CareTaker和Originator管理備忘錄類
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;

namespace MementoPattern
{
    /// <summary>
    /// 備忘錄類
    /// </summary>
    public class Memento<T>
    {
        T state;
        public Memento(T state)
        {
            this.state = state;
        }

        public T GetState()
        {
            return state;
        }
    }

    public class Originator<T>
    {
        T state;

        public void SetState(T memento)
        {
            this.state = memento;
        }

        public T GetState()
        {
            return state;
        }

        public Memento<T> SaveStateToMemento()
        {
            return new Memento<T>(state);
        }

        public void GetStateFromMemento(Memento<T> Memento)
        {
            state = Memento.GetState();
        }
    }

    public class CareTaker<T>
    {
        List<Memento<T>> mementos = new List<Memento<T>>();

        public void Add(Memento<T> memento)
        {
            mementos.Add(memento);
        }

        public Memento<T> GetMemento(int index)
        {
            return mementos[index];
        }
    }


    internal class MementoPatternMain : IPattern
    {
        public void Main()
        {
            Originator<string> originator = new Originator<string>();
            CareTaker<string> careTaker = new CareTaker<string>();
            originator.SetState("State #1");
            originator.SetState("State #2");
            careTaker.Add(originator.SaveStateToMemento());
            originator.SetState("State #3");
            careTaker.Add(originator.SaveStateToMemento());
            originator.SetState("State #4");

            Console.WriteLine(("Current State: " + originator.GetState()));
            originator.GetStateFromMemento(careTaker.GetMemento(0));
            Console.WriteLine("First saved State: " + originator.GetState());
            originator.GetStateFromMemento(careTaker.GetMemento(1));
            Console.WriteLine("Second saved State: " + originator.GetState());
        }
    }
}

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市臼婆,隨后出現(xiàn)的幾起案子抒痒,更是在濱河造成了極大的恐慌,老刑警劉巖颁褂,帶你破解...
    沈念sama閱讀 218,451評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件故响,死亡現(xiàn)場離奇詭異,居然都是意外死亡颁独,警方通過查閱死者的電腦和手機彩届,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來誓酒,“玉大人惨缆,你說我怎么就攤上這事》峤荩” “怎么了坯墨?”我有些...
    開封第一講書人閱讀 164,782評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長病往。 經(jīng)常有香客問我捣染,道長,這世上最難降的妖魔是什么停巷? 我笑而不...
    開封第一講書人閱讀 58,709評論 1 294
  • 正文 為了忘掉前任耍攘,我火速辦了婚禮,結果婚禮上畔勤,老公的妹妹穿的比我還像新娘蕾各。我一直安慰自己,他們只是感情好庆揪,可當我...
    茶點故事閱讀 67,733評論 6 392
  • 文/花漫 我一把揭開白布式曲。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪吝羞。 梳的紋絲不亂的頭發(fā)上兰伤,一...
    開封第一講書人閱讀 51,578評論 1 305
  • 那天,我揣著相機與錄音钧排,去河邊找鬼敦腔。 笑死,一個胖子當著我的面吹牛恨溜,可吹牛的內(nèi)容都是我干的符衔。 我是一名探鬼主播,決...
    沈念sama閱讀 40,320評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼糟袁,長吁一口氣:“原來是場噩夢啊……” “哼判族!你這毒婦竟也來了?” 一聲冷哼從身側響起系吭,我...
    開封第一講書人閱讀 39,241評論 0 276
  • 序言:老撾萬榮一對情侶失蹤五嫂,失蹤者是張志新(化名)和其女友劉穎颗品,沒想到半個月后肯尺,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,686評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡躯枢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,878評論 3 336
  • 正文 我和宋清朗相戀三年则吟,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片锄蹂。...
    茶點故事閱讀 39,992評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡氓仲,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出得糜,到底是詐尸還是另有隱情敬扛,我是刑警寧澤,帶...
    沈念sama閱讀 35,715評論 5 346
  • 正文 年R本政府宣布朝抖,位于F島的核電站啥箭,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏治宣。R本人自食惡果不足惜急侥,卻給世界環(huán)境...
    茶點故事閱讀 41,336評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望侮邀。 院中可真熱鬧坏怪,春花似錦、人聲如沸绊茧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽华畏。三九已至捉超,卻和暖如春胧卤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背拼岳。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評論 1 270
  • 我被黑心中介騙來泰國打工枝誊, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人惜纸。 一個月前我還...
    沈念sama閱讀 48,173評論 3 370
  • 正文 我出身青樓叶撒,卻偏偏與公主長得像,于是被迫代替她去往敵國和親耐版。 傳聞我的和親對象是個殘疾皇子祠够,可洞房花燭夜當晚...
    茶點故事閱讀 44,947評論 2 355

推薦閱讀更多精彩內(nèi)容