設計模式 - 責任鍊模式

  • 1733
  • 0
  • 2018-04-01

此篇簡單介紹責任鍊模式.

使用情境: 
        在很多情況下, 例如網頁抓取往往會因為要抓取不同的標籤內文寫出不同的判斷. 若需求一直變動或者條件一直增加會導致需求變動時不易修改, 條件增加時要修改主程式. 這樣的結果往往會導致程式碼難以維護以及增加修改風險.

原理:
        將每個判斷的條件轉換成物件, 並讓物件自身去判定自己有沒有需要, 若不需要則交由下一個物件.


 

類別圖 : 

 抽象類 :

namespace 責任鍊模式
{
    /// <summary>
    /// 由子類去判斷是否有需要處理, 不管子類需不需要執行最後都透過抽象類的方法來管理流程.
    /// </summary>
    abstract class AbstactMonkey
    {
        private AbstactMonkey _NextMonkey;

        public AbstactMonkey(AbstactMonkey setMonkey)
        {
            this._NextMonkey = setMonkey;
        }

        // 開始在物件中尋找責任
        public void DoSomething(DayOfWeek dayOfWeek)
        {            
            if (this.isMyResponsibility(dayOfWeek)) // 請子類判斷是否是她的責任
            {
                this.MyAction(dayOfWeek);
                Console.WriteLine("責任鏈結束");
            }               
            else
            {
                Console.WriteLine("找尋N次");
                if (this._NextMonkey != null) // 請下一個子類做判斷
                    this._NextMonkey.DoSomething(dayOfWeek);
                else
                    Console.WriteLine("找無負責的物件");
            }
            
        }

        protected abstract void MyAction(DayOfWeek dayOfWeek);

        protected abstract bool isMyResponsibility(DayOfWeek dayOfWeek);
    }
}

 

實作類 : 

namespace 責任鍊模式
{
    class MondayMonkey : AbstactMonkey
    {
        public MondayMonkey(AbstactMonkey setMonkey) : base(setMonkey)
        {
        }

        protected override bool isMyResponsibility(DayOfWeek dayOfWeek)
        {
            if (dayOfWeek == DayOfWeek.Monday)
                return true;
            return false;
        }

        protected override void MyAction(DayOfWeek dayOfWeek)
        {
            Console.WriteLine("星期一的猴子: 星期一穿新衣");
        }
    }

    class TuesdayMonkey : AbstactMonkey
    {
        public TuesdayMonkey(AbstactMonkey setMonkey) : base(setMonkey)
        {
        }

        protected override bool isMyResponsibility(DayOfWeek dayOfWeek)
        {
            if (dayOfWeek == DayOfWeek.Tuesday)
                return true;
            return false;
        }

        protected override void MyAction(DayOfWeek dayOfWeek)
        {
            Console.WriteLine("星期二的猴子: 星期二穿新衣");
        }
    }

    class WednesdayMonkey : AbstactMonkey
    {
        public WednesdayMonkey(AbstactMonkey setMonkey) : base(setMonkey)
        {
        }

        protected override bool isMyResponsibility(DayOfWeek dayOfWeek)
        {
            if (dayOfWeek == DayOfWeek.Wednesday)
                return true;
            return false;
        }

        protected override void MyAction(DayOfWeek dayOfWeek)
        {
            Console.WriteLine("星期三的猴子: 星期三穿新衣");
        }
    }

    class ThursdayMonkey : AbstactMonkey
    {
        public ThursdayMonkey(AbstactMonkey setMonkey) : base(setMonkey)
        {
        }

        protected override bool isMyResponsibility(DayOfWeek dayOfWeek)
        {
            if (dayOfWeek == DayOfWeek.Thursday)
                return true;
            return false;
        }

        protected override void MyAction(DayOfWeek dayOfWeek)
        {
            Console.WriteLine("星期四的猴子: 星期四穿新衣");
        }
    }

    class FridayMonkey : AbstactMonkey
    {
        public FridayMonkey(AbstactMonkey setMonkey) : base(setMonkey)
        {
        }

        protected override bool isMyResponsibility(DayOfWeek dayOfWeek)
        {
            if (dayOfWeek == DayOfWeek.Friday)
                return true;
            return false;
        }

        protected override void MyAction(DayOfWeek dayOfWeek)
        {
            Console.WriteLine("星期五的猴子: 星期五穿新衣");
        }
    }

    class SaturdayMonkey : AbstactMonkey
    {
        public SaturdayMonkey(AbstactMonkey setMonkey) : base(setMonkey)
        {
        }

        protected override bool isMyResponsibility(DayOfWeek dayOfWeek)
        {
            if (dayOfWeek == DayOfWeek.Saturday)
                return true;
            return false;
        }

        protected override void MyAction(DayOfWeek dayOfWeek)
        {
            Console.WriteLine("星期六的猴子: 星期六穿新衣");
        }
    }

    class SundayMonkey : AbstactMonkey
    {
        public SundayMonkey(AbstactMonkey setMonkey) : base(setMonkey)
        {
        }

        protected override bool isMyResponsibility(DayOfWeek dayOfWeek)
        {
            if (dayOfWeek == DayOfWeek.Sunday)
                return true;
            return false;
        }

        protected override void MyAction(DayOfWeek dayOfWeek)
        {
            Console.WriteLine("星期日的猴子: 星期日穿新衣");
        }
    }
}

 

用戶端 : 

namespace 責任鍊模式
{
    class Program
    {
        static void Main(string[] args)
        {
            // 情境: 每天有不同的猴子會做一件事, 一個禮拜七天就有七隻猴子. 
            // 如果使用傳統的寫法正常會包在switch..case中. switch(today){ case Monday: do..; break; case ......}

            var today = DayOfWeek.Friday;

            // 將判斷的條件通通塞入, 最後一個條件建構參數須為null.
            var monkey =new FridayMonkey(new MondayMonkey(new TuesdayMonkey(
                new WednesdayMonkey(new SaturdayMonkey(new ThursdayMonkey(new SundayMonkey(null)))))));

            monkey.DoSomething(today);

            Console.Read();
        }
    }
}

結果顯示 : 

 


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

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