一、什麼是職責鍊模式
使多個對象都有機會處理請求,進而避免請求的發送者和接收者之間的耦合關系.
将這個對象連成一條鍊,并沿着這條鍊傳遞該請求,直到有一個對象處理它為止.當客戶送出一個請求時,請求是沿鍊傳遞直至有一個職責負責處理它.職責單一不彼依賴,處理完并自動轉移.職責模式每個單鍊不必知道下一個鍊是誰,這些由環境設定.
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:職責鍊模式和 狀态模式有些類似,不過兩者還是有很大差別,狀态模式的狀态過渡是在編譯時就已經确定了,不同狀态之間的轉換,但是職責鍊模式的職責轉換是在環境中給定的,也可以修改替換,顯得更靈活。