第一章 策略模式

《Head First 設計模式》學習心得


策略模式

定義

策略模式定義了算法族,分別封裝起來。讓他們之間可以相互替換,此模式讓算法的變化獨立於使用算法的客戶。每個行爲接口和它的各個實現組成一個算法族,算法族中的每個具體實現是可以互相替換的。

設計原則:

  1. 把代碼中將來可能變化的部分抽離出來,獨立封裝;
  2. 針對接口編程,而不是針對實現編程;
  3. 多用組合,少用繼承。
    兩條原則,說白了都是變與不變的分離,第一條原則其實是目的,第二條原則是手段。

心得

設計的目標是要儘可能的重用代碼,也就是能少幹就少乾點,時間節省下來喝茶聊天也比擼代碼強。實現代碼重用的重要手段是繼承。子類公共的東西,在父類中實現,那麼在子類中就不用再敲一遍代碼了。在現實情況中,會有這種情況,就是某個東西一些子類中有,一些子類中沒有,而且將來說不好新子類中有沒有或者不一樣。那怎麼辦呢?
這部分就是可變的,要抽離出來,每一個功能用一個接口,接口就是功能的抽象,比如飛翔,飛的姿勢有很多種,那麼這個接口就是飛翔。具體的飛翔功能,就用一個具體類去實現這個接口。
在要重用的基類中聲明接口類型的字段,調用接口中的方法。在子類中,給從父類繼承而來的字段賦予具體接口實現。這樣基類就不用老是改變了。
至此基類的結構是這樣的:不變的部分,可變部分的接口;
子類中的結構是這樣的:父類的不變的部分,可變部分的接口的具體對象賦值,擴展的部分。

示例代碼

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 設計模式入門
{
    class Program
    {
        static void Main(string[] args)
        {
            // 消費子類
            var mallardDuck=new MallardDuck();
            mallardDuck.SetFlyBehavior(new FlyWithWind());
            mallardDuck.SetQuackBehavior(new MallerdDuckQuack());
            mallardDuck.PerformQuack();
            mallardDuck.PerformFly();
            Console.ReadKey();
        }
    }

    #region 以下是變得部分

    public class MallardDuck : Duck
    {
        // 具體的子類
        public MallardDuck()
        {


        }

        #region 動態設定類型

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

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

        #endregion

        public void Display()
        {
            Console.WriteLine("I'm a real Mallard duck");
        }
    }


    // 行爲接口的具體實現
    public class MallerdDuckQuack : IQuackBehavior
    {
        public void Quack()
        {
            Console.WriteLine("I'm a mallard duck. Ga ga ...");
        }
    }

    // 行爲接口的具體實現
    public class FlyWithWind : IFlyBehavior
    {
        public void Fly()
        {
            Console.WriteLine("I'm a mallard duck. I'm flying with the wind.");
        }
    }

    #endregion

    #region 以下是不變的部分

    public class Duck
    {
        // 用接口作爲基類的字段
        public IQuackBehavior QuackBehavior;
        public IFlyBehavior FlyBehavior;

        // 調用接口的方法
        public void PerformQuack()
        {
            QuackBehavior.Quack();
        }

        // 調用接口的方法
        public void PerformFly()
        {
            FlyBehavior.Fly();
        }
    }

    // 行爲抽象爲接口
    public interface IFlyBehavior
    {
        void Fly();
    }

    // 行爲抽象爲接口
    public interface IQuackBehavior
    {
        void Quack();
    }

    #endregion

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章