責任鏈模式(Chain of Responsibility Pattern)為請求創建了一個接收者對象的鏈。這種模式給予請求的類型,對請求的發送者和接收者進行解耦。這種類型的設計模式屬於行為型模式。
在這種模式中,通常每個接收者都包含對另一個接收者的引用。如果一個對象不能處理該請求,那么它會把相同的請求傳給下一個接收者,依此類推。
通過以下一個場景,以代碼的形式進行說明責任鏈的實現
人物:
員工(Staff):小明、組長(GroupLeader):李磊、課長(Charge):張越、部長(minister):任盈盈、總經理(Manager):令狐沖
職位關系:
員工<組長<課長<部長
情景:
小明剛認識了一個女孩(菜花),想請假找她玩,以增進和她的感情。
請假流程:
請假8小時以內,組長可以決定,超過8小時則需要課長審批,
請假16小時以內,課長可以決定,超過16小時則需要部長審批,
請假24小時以內,部長可以決定,超過24小時則需要總經理審批,
請假32小時以內,總經理可以決定,超過32小時審批不通過
開始:
打開VS,新建控制台應用程序,添加申請請假單類:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DesignConsoleApp1 { /// <summary> /// 請假申請單 /// </summary> public class ApplyContext { /// <summary> /// 請假人 /// </summary> public String Name { get; set; } /// <summary> /// 請假小時數 /// </summary> public int Hour { get; set; } /// <summary> /// 審核是否通過 /// </summary> public Boolean IsAuditing { get; set; } /// <summary> /// 審核建議 /// </summary> public String Opinion { get; set; } } }
添加審核基類(抽象類)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DesignConsoleApp1 { /// <summary> /// 審核基類 /// </summary> public abstract class BaseAuditor { /// <summary> /// 審核人 /// </summary> public String Name { get; set; } /// <summary> /// 這個很關鍵,代表下一個審核人 /// </summary> public BaseAuditor _nextAuditor { get; private set; } /// <summary> /// 設置下一個審核人 /// </summary> /// <param name="baseAuditor"></param> public void setNextAuditor(BaseAuditor baseAuditor) { this._nextAuditor = baseAuditor; } /// <summary> /// 審核方法 /// </summary> /// <param name="applyContext"></param> public abstract void auditor(ApplyContext applyContext); //員工(Staff):小明、組長(GroupLeader):李磊、課長(Charge):張越、部長(minister):任盈盈、總經理(Manager):令狐沖 } }
添加組長(GroupLeader),繼承審核基類
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DesignConsoleApp1 { /// <summary> /// 組長類 /// </summary> public class GroupLeader : BaseAuditor { /// <summary> /// 實現基類的抽象審核方法 /// </summary> /// <param name="applyContext"></param> public override void auditor(ApplyContext applyContext) { if (applyContext.Hour <= 8) { applyContext.Opinion += "\n\r;" + base.Name + "組長審核通過"; } else { if (base._nextAuditor != null) { base._nextAuditor.auditor(applyContext); } else { applyContext.Opinion += "\n\r;" + base.Name + "組長審核沒有通過,理由:時間太長"; } } } } }
課長(Charge)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DesignConsoleApp1 { /// <summary> /// 課長類 /// </summary> public class Charge : BaseAuditor { /// <summary> /// 實現基類的抽象審核方法 /// </summary> /// <param name="applyContext"></param> public override void auditor(ApplyContext applyContext) { if (applyContext.Hour <=16 ) { applyContext.Opinion += "\n\r;" + base.Name + "課長審核通過"; } else { if (base._nextAuditor != null) { base._nextAuditor.auditor(applyContext); } else { applyContext.Opinion += "\n\r;" + base.Name + "課長審核沒有通過,理由:時間太長"; } } } } }
部長(minister)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DesignConsoleApp1 { /// <summary> /// 部長類 /// </summary> public class Minister : BaseAuditor { /// <summary> /// 實現基類的抽象審核方法 /// </summary> /// <param name="applyContext"></param> public override void auditor(ApplyContext applyContext) { if (applyContext.Hour <= 8) { applyContext.Opinion += "\n\r;" + base.Name + "部長審核通過"; } else { if (base._nextAuditor != null) { base._nextAuditor.auditor(applyContext); } else { applyContext.Opinion += "\n\r;" + base.Name + "部長審核沒有通過,理由:時間太長"; } } } } }
總經理(Manager)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DesignConsoleApp1 { /// <summary> /// 總經理類 /// </summary> public class Manager : BaseAuditor { /// <summary> /// 實現基類的抽象審核方法 /// </summary> /// <param name="applyContext"></param> public override void auditor(ApplyContext applyContext) { if (applyContext.Hour <= 8) { applyContext.Opinion += "\n\r;" + base.Name + "總經理審核通過"; } else { if (base._nextAuditor != null) { base._nextAuditor.auditor(applyContext); } else { applyContext.Opinion += "\n\r;" + base.Name + "總經理審核沒有通過,理由:時間太長"; } } } } }
層級關系類,職位人員的創建及職位關系的建立
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DesignConsoleApp1 { /// <summary> /// 層級關系類,職位人員的創建及職位關系的建立 /// </summary> public class Relationship { private static BaseAuditor baseAuditor; static Relationship() { Manager manager = new Manager() { Name="令狐沖" }; Minister minister = new Minister() { Name = "任盈盈", }; Charge charge = new Charge() { Name="張越"}; GroupLeader groupLeader = new GroupLeader() { Name = "小明" }; //設置上下級關系 groupLeader.setNextAuditor(charge); charge.setNextAuditor(minister); minister.setNextAuditor(manager); baseAuditor = groupLeader; } public static BaseAuditor getBaseAuditor() { return baseAuditor; } } }
請假情景開始:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DesignConsoleApp1 { class Program { static void Main(string[] args) { bool bo = true; ApplyContext applyContext = new ApplyContext() { Name="小明", Opinion= "請假理由:為了祖國下一代,約個妹子談戀愛\n\r" }; BaseAuditor baseAuditor = Relationship.getBaseAuditor(); while (bo) { Console.WriteLine("請輸入大於0的請假小時數,0或者非數字會退出"); try { applyContext.Hour= int.Parse( Console.ReadLine()); //審核 baseAuditor.auditor(applyContext); if (applyContext.IsAuditing) { Console.WriteLine(applyContext.Opinion + "\n\r打電話給胖妞,親愛的胖妞,我的請假通過了\n\r胖妞說:好的,我給你做你最喜歡吃的酸菜"); } else { Console.WriteLine(applyContext.Opinion + "\n\r打電話給胖妞,胖妞,我的請假沒有通過了\n\r胖妞說:你可以請假時間短一點,你再試試"); } applyContext.Opinion = ""; Console.WriteLine("================================="); } catch (Exception ex) { Console.WriteLine(ex.Message); bo = false; } } Console.Read(); } } }


