設計模式 - 策略模式

  • 1283
  • 0

此篇簡單介紹策略模式。

關注在 :

  • 降低耦合提高聚合
  • 聚焦於高階模組與低階模組所依賴的抽象,而不是實作類別
  • 因應設計時期的需求去動態切換該使用哪種行為

要點 :

  • 高度的使用介面(抽象)
  • 針對介面(抽象)來思考而非針對實踐
  • 多用合成少用繼承
  • 適度的使用命名空間管理同一類型的介面或者子類
  • 妥善應用 private protected public internal sealed 修飾詞
  • 理解 interface 與 abstract 的使用方法

 

類別圖 : 

 

高階模組 - 抽象類 :

using StrategyPatternSample.CAR.interfaceForCar;

namespace StrategyPatternSample.CAR
{

    /// <summary>
    /// 基底類別擺放處
    /// 此為規範衍生類別所有抽象方法的參數規則
    /// 使用介面抽離真正實作的方法
    /// </summary>
    abstract internal class AbstractCar
    {
        //Note : 若不想讓外部引用衍生類別時要還要自己實例化出物件當參數傳入衍生類別對應的方法,可用以下方式解套 : 
        // 在基底類別中提供列舉或字典,思考後若將列舉分類會導致外部引用時混亂可暫時只用一個列舉取代
        // 再想辦法透過基底類別或衍生類別根據列舉去產生對應的實例,或者透過工廠

        abstract public void SpeedUp(ISpeedUpSet SpeedUpChance);

        abstract public void SpeedDown(ISpeedDownSet SpeedDownChance);

        abstract public void UseNOS(IUseNOSSet UseNOS_Chance);

        abstract public void AtkMode(IAtkModeSet AtkModeChance);
    }
}

 

高階模組 - 實作類 :

using StrategyPatternSample.CAR.interfaceForCar;

namespace StrategyPatternSample.CAR
{
    /// <summary>
    /// 衍生類別 : 參數的規範於父類別中就已經設定完成
    /// </summary>
    sealed internal class ExtendCar1 : AbstractCar
    {
        
        public override void AtkMode(IAtkModeSet AtkModeChance)
        {
            AtkModeChance.AtkMode();            
        }

        public override void SpeedDown(ISpeedDownSet SpeedDownChance)
        {
            SpeedDownChance.SpeedDown();
        }

        public override void SpeedUp(ISpeedUpSet SpeedUpChance)
        {
            SpeedUpChance.SeedUp();
        }

        public override void UseNOS(IUseNOSSet UseNOS_Chance)
        {
            UseNOS_Chance.UseNOS();
        }
    }
}

 

低階模組 - 抽象類 :

using System;

/// <summary>
/// 此為介面規範 讓父類能指定相關參數依此類型來接收
/// 真正實作細節的部分也在此
/// </summary>
namespace StrategyPatternSample.CAR
{
    namespace interfaceForCar
    {
        #region 規範介面
        internal interface ISpeedUpSet
        {            
            void SeedUp();
        }
        internal interface ISpeedDownSet
        {
            void SpeedDown();
        }
        internal interface IUseNOSSet
        {
            void UseNOS();
        }
        internal interface IAtkModeSet
        {
            void AtkMode();
        }
        #endregion
    }
}

 

低階模組 - 實作類 : 

using System;

/// <summary>
/// 此為介面規範 讓父類能指定相關參數依此類型來接收
/// 真正實作細節的部分也在此
/// </summary>
namespace StrategyPatternSample.CAR
{
    namespace interfaceForCar
    {
        #region 規範介面實作類別
        /// <summary>
        /// 速度增加類別繼承自 ISpeedUpSet
        /// </summary>
        sealed internal class HighSpeed1 : ISpeedUpSet
        {
            public void SeedUp()
            {
                Console.WriteLine("InterfaceForCarAction.ISpeedUpSet.HighSpeed1");
            }
        }

        /// <summary>
        /// 速度減少類別繼承自 ISpeedDownSet
        /// </summary>
        sealed internal class LowDown1 : ISpeedDownSet
        {
            public void SpeedDown()
            {
                Console.WriteLine("InterfaceForCarAction.ISpeedUpSet.LowDown1");
            }
        }

        /// <summary>
        /// 選擇氮氣類別繼承自 IUseNOSSet
        /// </summary>
        sealed internal class NOS1 : IUseNOSSet
        {
            public void UseNOS()
            {
                Console.WriteLine("InterfaceForCarAction.ISpeedUpSet.NOS1");
            }
        }

        /// <summary>
        /// 選擇武器類別繼承自 IAtkModeSet
        /// </summary>
        sealed internal class GunMode1 : IAtkModeSet
        {
            public void AtkMode()
            {
                Console.WriteLine("InterfaceForCarAction.ISpeedUpSet.GunMode1");
            }
        }

        /// <summary>
        /// 選擇武器類別繼承自 IAtkModeSet
        /// </summary>
        sealed internal class KnifeMode1 : IAtkModeSet
        {
            public void AtkMode()
            {
                Console.WriteLine("InterfaceForCarAction.ISpeedUpSet.KnifeMode1");
            }
        }
        #endregion
    }
}

 

用戶端 : 

using System;

namespace StrategyPatternSample
{
    class MainVoid
    {   
        static void Main(string[] args)
        {
            //實例CAR的衍生類別
            CAR.AbstractCar MyCar1 = new CAR.ExtendCar1();
            //選擇加速的模式 使用抽象方式實例化
            CAR.interfaceForCar.ISpeedUpSet MyCarSpeedUP = new CAR.interfaceForCar.HighSpeed1();
            MyCar1.SpeedUp(MyCarSpeedUP);

            //選擇武器模式 使用抽象方式實例化
            CAR.interfaceForCar.IAtkModeSet MyCarAtkMode1 = new CAR.interfaceForCar.KnifeMode1();
            MyCar1.AtkMode(MyCarAtkMode1);
            //切換武器 只需更改傳遞的物件參數
            MyCarAtkMode1 = null;
            MyCarAtkMode1 = new CAR.interfaceForCar.GunMode1();
            MyCar1.AtkMode(MyCarAtkMode1);
            Console.Read();            
        }
    }
}

 

結果顯示 : 

 


多多指教!! 歡迎交流!!

你不知道自己不知道,那你會以為你知道