天天看點

大話設計模式:職責鍊模式

一、什麼是職責鍊模式

使多個對象都有機會處理請求,進而避免請求的發送者和接收者之間的耦合關系.
           

将這個對象連成一條鍊,并沿着這條鍊傳遞該請求,直到有一個對象處理它為止.當客戶送出一個請求時,請求是沿鍊傳遞直至有一個職責負責處理它.職責單一不彼依賴,處理完并自動轉移.職責模式每個單鍊不必知道下一個鍊是誰,這些由環境設定.

UML圖
           
大話設計模式:職責鍊模式

Handler: 操作類,設定下一個職責的方法,和一個目前處理職責的抽象方法.

ConcreteHandlerA:具體操作類A,現實具體目前職責

Client:環境類,負責給定職責鍊條

二、适用場景

職責子產品連結并不固定,可以靈活調整的情況.

在不明确指定接收者的情況下,向多個對象中的一個送出一個請求。可動态指定一組對象處理請求。比如擊鼓傳花,一個選手處理完之後交給下一位.

三、優缺點

優點

降低耦合度,請求與接收耦合度降低

接收職責之間解耦合,隻需關注自身的部分,不屬自身部分的内容交給下一個職責鍊,并不必關心是誰.

可靈活調整職責鍊的布局,增加替換或删除都很友善.

缺點

不能保證請求一定被接收.

系統性能的繁複度增加,調試時不太友善,可能會造成循環調用.

不容易觀察運作時的特征,有礙于除錯.

四、大話中的例子

公司管理人員處理員工請求, 經理/總監/總經理分别的處理權限是不一樣的. 大家都繼承一個管理者類, 這個類裡面做兩件事,①設定下一個連結者,②規定處理方案抽象方法. 這些管理者都繼承與它,實作抽象方法,依照自己的職責處理.

環境類裡面執行個體不同的管理者,然後給管理者設定職責鍊條.最後發送請求.

五、我的例子

using System;


namespace ChainOfResposMode
{
    class Program
    {
        static void Main(string[] args)
        {

            Ninja ninja1 = new Crew();
            Ninja ninja2 = new Captain();
            Ninja ninja3 = new Leader();
            ninja1.SetSuperior(ninja2);
            ninja2.SetSuperior(ninja3);
            Console.WriteLine("=====================================");
            ninja1.FindEnemy(1);
            Console.WriteLine("=====================================");
            ninja1.FindEnemy(3);
            Console.WriteLine("=====================================");
            ninja1.FindEnemy(7);
            Console.WriteLine("=====================================");
            ninja1.FindEnemy(10);
            Console.WriteLine("=====================================");
            ninja1.FindEnemy(500);
        }
    }

    abstract class Ninja
    {
        string name;

        protected Ninja ninja;

        public string Name { get => name; set => name = value; }

        public void SetSuperior(Ninja ninja)
        {
            this.ninja = ninja;
        }
        public abstract void FindEnemy(int enemynum);
    }

    class Crew : Ninja
    {
        public override void FindEnemy(int enemynum)
        {
            if (enemynum < 2)
            {
                Console.WriteLine("{1},對面隻有{0}人,幹掉他", enemynum, this.GetType().Name);
            }
            else
            {
                Console.WriteLine("{0},人太多,我拿不定主意", GetType().Name);
                ninja.FindEnemy(enemynum);
            }
        }
    }

    class Captain : Ninja
    {
        public override void FindEnemy(int enemynum)
        {
            if (enemynum < 5)
            {
                Console.WriteLine("{1},對面有{0}人,配合好,一起上", enemynum, this.GetType().Name);
            }
            else
            {
                Console.WriteLine("{0},人太多,我拿不定主意", GetType().Name);
                ninja.FindEnemy(enemynum);
            }
        }
    }

    class Leader : Ninja
    {
        public override void FindEnemy(int enemynum)
        {
            if (enemynum < 30)
            {
                Console.WriteLine("{1},對面有{0}人,我們做好戰略部署全殲敵人", enemynum, this.GetType().Name);
            }
            else
            {
                Console.WriteLine("{1},對面有{0}人,拼死守護村子", enemynum, this.GetType().Name);
            }
        }
    }
}

           
運作結果
           
大話設計模式:職責鍊模式

PS:職責鍊模式和 狀态模式有些類似,不過兩者還是有很大差別,狀态模式的狀态過渡是在編譯時就已經确定了,不同狀态之間的轉換,但是職責鍊模式的職責轉換是在環境中給定的,也可以修改替換,顯得更靈活。

繼續閱讀