【C#設計模式-責任鏈模式】
一.責任鏈模式的定義:
責任鏈模式指的是——某個請求需要多個物件進行處理,從而避免請求的傳送者和接收之間的耦合關係。將這些物件連成一條鏈子,並沿著這條鏈子傳遞該請求,直到有物件處理它為止。
二.責任鏈模式的結構和角色:
抽象處理者(Handler)角色:
定義出一個處理請求的介面。如果需要,介面可以定義 出一個方法以設定和返回對下家的引用。
具體處理者(ConcreteHandler)角色:
具體處理者接到請求後,可以選擇將請求處理掉,或者將請求傳給下家。由於具體處理者持有對下家的引用,因此,如果需要,具體處理者可以訪問下家。
三.責任鏈模式的實現:
在生活中,公司部門舉辦活動需要申請金費,如果金費<=1000,部門經理就可以批准發放,如果金額超過1000而<=5000,部門經理無權力批准,副總經理可以批准發放,如果金額超過5000而<=10000,副總經理沒有權力批准,此時只有總經理可以批准,而超過10000,就要就行會議決定。對於這樣的需求,每個角色的責任是不一樣的,如果使用傳統的方式,可能是寫個if多條件判斷,可以滿足現有的需要,但是後面增加新的角色賦予責任,就需要改變if結構判斷,違背設計原則中的對擴充套件開發,對修改關閉原則。使用責任鏈模式可以很方便的擴充套件。
/// <summary> /// 行為請求 /// </summary> public class BehaviourRequest { /// <summary> /// 金額 /// </summary> public double Money { get; set; } /// <summary> /// 活動名稱 /// </summary> public string ActiveName { get; set; } public BehaviourRequest(double money, string activename) { this.Money = money; this.ActiveName = activename; } }
/// <summary> /// 角色抽象類 /// </summary> public abstract class RoleAbstract { public RoleAbstract NextRole { get; set; } public string name { get; set; } public RoleAbstract(string name) { this.name = name; } /// <summary> /// 該角色的執行行為 /// </summary> public abstract void Behaviour(BehaviourRequest request); }
/// <summary>
/// 部門經理
/// </summary>
public class ManagerRole:RoleAbstract
{
public ManagerRole(string name) : base(name) { }
public override void Behaviour(BehaviourRequest request)
{
if (request.Money <= 1000)
{
Console.WriteLine("{0}的請求批准得到{1}批准,需要金額:{2}", request.ActiveName,this.name, request.Money);
}
else if (NextRole != null)
{
Console.WriteLine("{0}無權力批准,給上級{0}處理!", this.name, NextRole.name);
NextRole.Behaviour(request);
}
}
}
/// <summary>
/// 副總經理角色
/// </summary>
public class PresidentRole:RoleAbstract
{
public PresidentRole(string name) : base(name) { }
public override void Behaviour(BehaviourRequest request)
{
if (request.Money <= 5000)
{
Console.WriteLine("{0}的請求批准得到{1}批准,需要金額:{2}", request.ActiveName, this.name, request.Money);
}
else if (NextRole != null)
{
Console.WriteLine("{0}無權力批准,給上級{0}處理!", this.name, NextRole.name);
NextRole.Behaviour(request);
}
}
}
/// <summary>
/// 總經理
/// </summary>
public class PresidengtRole:RoleAbstract
{
public PresidengtRole(string name) : base(name) { }
public override void Behaviour(BehaviourRequest request)
{
if (request.Money <= 10000)
{
Console.WriteLine("{0}的請求批准得到{1}批准,需要金額:{2}", request.ActiveName, this.name, request.Money);
}
else
{
Console.WriteLine("這個活動需要進行會議討論決定");
}
}
}
/// <summary>
/// C#設計模式-責任鏈模式
/// </summary>
class Program
{
static void Main(string[] args)
{
//活動資訊
BehaviourRequest behavior = new BehaviourRequest(10000, "部門招商活動");
//對該活動的審批可能涉及的角色
RoleAbstract manager = new ManagerRole("部門經理");
RoleAbstract vp = new PresidentRole("副總經理");
RoleAbstract pre = new PresidengtRole("總經理");
//設定責任鏈
manager.NextRole = vp;
vp.NextRole = pre;
//請求處理
manager.Behaviour(behavior);
}
}
執行結果:
在進行10000元活動的審批過程中,首先通過部門經理,轉交給副總經理,然後再到總經理,根據每個角色的責任進行判斷,當無許可權批准某一行為請求的時候,就交個上一級進行處理。
四.責任鏈模式的適用場景:
一個系統的審批需要多個物件才能完成處理的情況下,例如請假系統等。
程式碼中存在多個if-else語句的情況下,此時可以考慮使用責任鏈模式來對程式碼進行重構。
五.責任鏈模式的優缺點:
優點:
降低了請求的傳送者和接收者之間的耦合。
把多個條件判定分散到各個處理類中,使得程式碼更加清晰,責任更加明確。
缺點:
在找到正確的處理物件之前,所有的條件判定都要執行一遍,當責任鏈過長時,可能會引起效能的問題
可能導致某個請求不被處理。