設計模式之職責鏈模式

1.職責鏈模式的意圖

通過給多個對象處理請求的機會,以解除請求的發送者與接收者之間的耦合。將這個對象連成一條鏈,並沿着這條鏈傳遞該請求,直到有一個對象處理它爲止。(客戶端不必事先知道對象集合中哪個對象可提供自己需要的服務)

2.職責鏈模式舉例

       比如,班裏想申請一個教室舉辦元旦晚會,文藝委員不能自作主張使用某個教室,於是找到班長,班長要做的就是寫申請,向負責人員申請,負責人批准以後才能使用教室,這一步步的過程就像是一條鏈,從某一點開始執行,不能通過的話就向後走,知道找到某一點能解決了問題才終止。問題只要解決了就達到了目的,不用考慮中間有多少人蔘與過,也就是隻關心結果
此班學生的動機可以表示成如圖:


3.職責鏈模式解讀


角色:

  • Client:客戶端
  • Handler: 抽象處理者:定義出一個處理請求的接口。如果需要,接口可以定義出一個方法以設定和返回對下家的引用。這個角色通常由一個抽象類或接口實現
  • ConcreteHandler:具體處理者:具體處理者接到請求後,可以選擇將請求處理掉,或者將請求傳給下家。由於具體處理者持有對下家的引用,因此,如果需要具體處理者可以訪問下家
代碼實現:

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

namespace 職責鏈模式
{
    class Program
    {
        static void Main(string[] args)
        {
            //設置職責鏈上家與下家
            Handler h1 = new ConcreteHandler1();
            Handler h2 = new ConcreteHandler2();
            Handler h3 = new ConcreteHandler3();
            h1.SetSuccessor(h2);
            h2.SetSuccessor(h3);

            int[] requests = { 2, 5, 14, 22, 18, 3, 27, 20 };
            foreach (int request in requests)
            {
               //循環給最小處理着提交請求,不同的數據由不同權限處理者處理
                h1.HandleRequest(request);
            }
            Console.Read();
        }
    }
    
    //Handler類,定義一個處理請示的接口
    abstract class Handler
    {
        protected Handler successor;

        //設置繼任者
        public void SetSuccessor(Handler successor)
        {
            this.successor = successor;
        }
         //處理請求的抽象方法
        public abstract void HandleRequest(int request);
    }
       
    
        //ConcreteHandler類,具體處理者類,處理它所負責的請求,可訪問它的後繼者,如果可處理該請求就處理它,否則就將該請求轉發給它的後繼者

        //ConcreteHandler1類,當請求數在0到10之間則有權處理,否則轉到下一位
        class ConcreteHandler1:Handler 
        {
            public override void HandleRequest(int request)
            {
                if (request >= 0 && request < 10)
                {
                    Console.WriteLine("{0}處理請求{1}", this.GetType ().Name , request);

                }
                else if (successor != null)
                {
                    //轉移到下一位
                    successor.HandleRequest(request);
            
                }
            }
         }
    
        //ConcreteHandler2類,當請求數在10到20之間則有權處理,否則轉到下一位

        class ConcreteHandler2 : Handler
        {
            public override void HandleRequest(int request)
            {
                if (request >= 10 && request < 20)
                {
                    Console.WriteLine("{0}處理請求{1}", this.GetType().Name, request);
                }
                else if (successor != null)
                {
                    successor.HandleRequest(request);
                }
            }
        }

       //ConcreteHandler3類,當請求數在20到30之間則有權處理,否則轉到下一位
        class ConcreteHandler3 : Handler
        {
            public override void HandleRequest(int request)
            {
                if (request >= 20 && request < 30)
                {
                    Console.WriteLine("{0}處理請求{1}", this.GetType().Name, request);
                }
                else if (successor != null)
                {
                    successor.HandleRequest(request);
                }
            }
        }
        
    }

運行結果:

4.職責鏈模式優缺點

 1)優點

  • 降低耦合度
  • 可簡化對象的相互連接
  • 增強給對象指派職責的靈活性
  • 方便增加新的類

 2)缺點

  • 請求到達末端也可能得不到處理
  • 代碼調試時不太方便,可能會造成循環調用
5.適用場合

  • 有多個對象可以處理同一個請求,具體哪個對象處理該請求由運行時刻自動確定
  • 在不明確指定接受者的情況下,向多個對象中的一個提交一個請求
  • 可動態指定一組對象處理請求

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