責任鏈設計模式,是行爲型設計模式的巔峯之做。設計模式
如今有一個場景,請假申請。請假時間的長短,須要不一樣級別的領導才能審批。ide
萬物皆對象嘛,請假須要工號、姓名、緣由、時長、結果等等,那咱們來定義一個請假的類。其實其就是一個上下文環境(Context),保存業務處理中參數-----中間結果-----最終結果。行爲型設計模式重用的標配,把行爲轉移。this
public class ApplyContext { public int Id { get; set; } public string Name { get; set; } /// <summary> /// 請假時長 /// </summary> public int Hour { get; set; } public string Description { get; set; } public bool AuditResult { get; set; } public string AuditRemark { get; set; } }
請假須要new一個實例:spa
ApplyContext context = new ApplyContext() { Id = 506, Name = "bingle", Hour = 100, Description = "世界那麼大,我想去看看!", AuditResult = false, AuditRemark = "" };
第一種方式,審批邏輯都寫在上端,直接就是需求翻譯,沒有任何加工,談不上什麼擴展,面向過程:翻譯
if (context.Hour <= 8) { Console.WriteLine("PM審批經過"); } else if (context.Hour <= 16) { Console.WriteLine("主管審批經過"); } else { Console.WriteLine("************"); }
第二種方式,面向對象:封裝--繼承--多態,轉移業務邏輯,也只是一個翻譯機,翻譯完+面向對象,其實徹底沒有涉及加工沒有思考。設計
領導類S:code
public class PM { public override void Audit(ApplyContext context) { Console.WriteLine($"This is {this.GetType().Name} {this.Name} Audit"); if (context.Hour <= 8) { context.AuditResult = true; context.AuditRemark = "容許請假!"; } } } public class Charge { public override void Audit(ApplyContext context) { Console.WriteLine($"This is {this.GetType().Name} {this.Name} Audit"); if (context.Hour <= 16) { context.AuditResult = true; context.AuditRemark = "容許請假!"; } } } public class Manager { public override void Audit(ApplyContext context) { Console.WriteLine($"This is {this.GetType().Name} {this.Name} Audit"); if (context.Hour <= 24) { context.AuditResult = true; context.AuditRemark = "容許請假!"; } } } public class Chief { public override void Audit(ApplyContext context) { Console.WriteLine($"This is {this.GetType().Name} {this.Name} Audit"); if (context.Hour <= 48) { context.AuditResult = true; context.AuditRemark = "容許請假!"; } } } public class CEO : AbstractAuditor { public override void Audit(ApplyContext context) { Console.WriteLine($"This is {this.GetType().Name} {this.Name} Audit"); if (context.Hour <= 96) { context.AuditResult = true; context.AuditRemark = "容許請假!"; } } } public class ChiarMan : AbstractAuditor { public override void Audit(ApplyContext context) { Console.WriteLine($"This is {this.GetType().Name} {this.Name} Audit"); if (context.Hour <= 1000000) { context.AuditResult = true; context.AuditRemark = "容許請假!"; } } }
下面進行邏輯的翻譯:對象
AbstractAuditor pm = new PM() { Name = "bingle1" }; pm.Audit(context); if (!context.AuditResult) { AbstractAuditor charge = new Charge() { Name = "bingle2" }; charge.Audit(context); if (!context.AuditResult) { AbstractAuditor manager = new Manager() { Name = "bingle3" }; manager.Audit(context); if (!context.AuditResult) { //找下一環節 } } }
不要直接翻譯的邏輯,須要涉及,如今的場景分析是,一、權限範圍內,審批經過;二、權限範圍外,交給下一環節審批,寫的代碼又多了一個,指定洗衣環節,甩鍋大法開始。blog
首先定義一個抽象父類:繼承
public abstract class AbstractAuditor { public string Name { get; set; } public abstract void Audit(ApplyContext context); private AbstractAuditor _NextAuditor = null; public void SetNext(AbstractAuditor auditor) { this._NextAuditor = auditor; } protected void AuditNext(ApplyContext context) { if (this._NextAuditor != null) { this._NextAuditor.Audit(context); } else { context.AuditResult = false; context.AuditRemark = "不容許請假!"; } } }
領導類須要繼承這個抽象類:
public class PM : AbstractAuditor { public override void Audit(ApplyContext context) { Console.WriteLine($"This is {this.GetType().Name} {this.Name} Audit"); if (context.Hour <= 8) { context.AuditResult = true; context.AuditRemark = "容許請假!"; } else { AbstractAuditor charge = new Charge() { Name = "象撲君" }; charge.Audit(context); } } }
其餘的領導類以此類推.....
調用的時候,只須要找最低權限的人,去審批
AbstractAuditor pm = new PM() { Name = "bingle" }; pm.Audit(context);
以上,轉移了申請提交的邏輯,此次符合實際狀況,有了本身的思考和設計在裏面。
甩鍋大法開始了,同樣,領導類須要實現抽象父類,不過在Audit方法中稍做了改動
public class PM : AbstractAuditor { public override void Audit(ApplyContext context) { Console.WriteLine($"This is {this.GetType().Name} {this.Name} Audit"); if (context.Hour <= 8) { context.AuditResult = true; context.AuditRemark = "容許請假!"; } else { base.AuditNext(context); } } } public class Manager : AbstractAuditor { public override void Audit(ApplyContext context) { Console.WriteLine($"This is {this.GetType().Name} {this.Name} Audit"); if (context.Hour <= 24) { context.AuditResult = true; context.AuditRemark = "容許請假!"; } else { base.AuditNext(context); } } } public class Chief : AbstractAuditor { public override void Audit(ApplyContext context) { Console.WriteLine($"This is {this.GetType().Name} {this.Name} Audit"); if (context.Hour <= 48) { context.AuditResult = true; context.AuditRemark = "容許請假!"; } else { base.AuditNext(context); } } } public class ChiarMan : AbstractAuditor { public override void Audit(ApplyContext context) { Console.WriteLine($"This is {this.GetType().Name} {this.Name} Audit"); if (context.Hour <= 1000000) { context.AuditResult = true; context.AuditRemark = "容許請假!"; } else { base.AuditNext(context); } } } public class Charge: AbstractAuditor { public override void Audit(ApplyContext context) { Console.WriteLine($"This is {this.GetType().Name} {this.Name} Audit"); if (context.Hour <= 16) { context.AuditResult = true; context.AuditRemark = "容許請假!"; } else { base.AuditNext(context); } } } public class CEO : AbstractAuditor { public override void Audit(ApplyContext context) { Console.WriteLine($"This is {this.GetType().Name} {this.Name} Audit"); if (context.Hour <= 96) { context.AuditResult = true; context.AuditRemark = "容許請假!"; } else { base.AuditNext(context); } } }
下面須要找領導審批了:
AbstractAuditor pm = new PM() { Name = "bingle1" }; AbstractAuditor charge = new Charge() { Name = "bingle1" }; AbstractAuditor manager = new Manager() { Name = "bingle1" }; AbstractAuditor chief = new Chief() { Name = "bingle1" }; AbstractAuditor ceo = new CEO() { Name = "bingle1" }; //pm.SetNext(charge); //charge.SetNext(manager); pm.SetNext(manager); manager.SetNext(chief); chief.SetNext(ceo); ceo.SetNext(new ChiarMan() { Name = "bingle1" }); //流程的可擴展 pm.Audit(context); if (!context.AuditResult) { Console.WriteLine("不幹了!"); }
以上,把流暢環節邏輯從業務類轉移了。