1:主題拆解
①基本介紹
②人事請假單作業流模擬
③責任鏈模式的優缺點
④適用場景
⑤應用實體
⑥ASP.NET 管道模型
2:基本介紹

責任鏈模式很像例外的捕獲和處理,當一個問題發生的時候,當前物件看一下自己是否能夠處理,不能的話將問題拋給自己的上級去處理,但是要注意這里的上級不一定指的是繼承關系的父類,這點和例外的處理是不一樣的,
所以可以這樣說,當問題不能解決的時候,將問題交給另一個物件去處理,就這樣一直傳遞下去直至當前物件找不到下線了,處理結束,
責任鏈可以是一條直線,一個環或者一個樹形結構,最常見的職責鏈是直線型,即沿著一條單向的鏈來傳遞請求,鏈上的每一個物件都是請求處理者,責任鏈模式可以將請求的處理者組織成一條鏈,并讓請求沿著鏈傳遞,由鏈上的處理者對請求進行處理,客戶端無須關系請求的處理細節以及具體的傳遞,只需要將請求發送到鏈上即可,實作請求發送者以及請求處理者的解耦,
3:人事請假單作業流模擬
今天我們通過原始碼模擬人事請假單作業流功能的實作來區分不同程式員對功能實作的風格,
需求:某一職員想請假10天,即80小時,
規則:8小時之內專案經理審核,16小時之內主管審核,32小時之內經理審核,64小時之內總監審核,128小時之內CEO審核,
咱們廢話不多說,開始擼碼
請假背景關系
public class ApplyContext
{
public int Id { get; set; }
public string Name { get; set; }
/// <summary>
/// 請假時長
/// </summary>
public int Hour { get; set; }
/// <summary>
/// 請假描述
/// </summary>
public string Description { get; set; }
/// <summary>
/// 審批結果,默認是false
/// </summary>
public bool AuditResult { get; set; }
/// <summary>
/// 審批備注
/// </summary>
public string AuditRemark { get; set; }
}
1:初級程式員
Console.WriteLine("這里是專案經理 {0} 審批", "fool");
if (context.Hour <= 8)
{
context.AuditResult = true;
context.AuditRemark = "enjoy your vacation!";
}
else
{
Console.WriteLine("這里是主管 {0} 審批", "fool");
if (context.Hour <= 16)
{
context.AuditResult = true;
context.AuditRemark = "enjoy your vacation!";
}
else
{
Console.WriteLine("這里是經理 {0} 審批", "fool");
if (context.Hour <= 32)
{
context.AuditResult = true;
context.AuditRemark = "enjoy your vacation!";
}
else
{
Console.WriteLine("這里是總監 {0} 審批", "fool");
if (context.Hour <= 64)
{
context.AuditResult = true;
context.AuditRemark = "enjoy your vacation!";
}
else
{
Console.WriteLine("這里是CEO {0} 審批", "fool");
if (context.Hour <= 128)
{
context.AuditResult = true;
context.AuditRemark = "enjoy your vacation!";
}
else
{
context.AuditResult = false;
context.AuditRemark = "reject!";
}
}
}
}
}
分析:
代碼翻譯機,需求怎么交代我們就怎么翻譯,完全沒有自己的加工,
把全部的業務邏輯都暴露在上端,面向程序式編程,
2:中級程式員
定義PM,主管,經理,總監,CEO物件
①物件抽象基類
public abstract class AbstractAuditor
{
public string Name { get; set; }
public abstract void Audit(ApplyContext context);
}
②各種物件實體類
public class PM : AbstractAuditor
{
public override void Audit(ApplyContext context)
{
Console.WriteLine("這里是專案經理 {0} 審批", this.Name);
if (context.Hour <= 8)
{
context.AuditResult = true;
context.AuditRemark = "enjoy your vacation!";
}
else
{
}
}
}
public class Charge: AbstractAuditor
{
public override void Audit(ApplyContext context)
{
Console.WriteLine("這里是主管 {0} 審批", this.Name);
if (context.Hour <= 16)
{
context.AuditResult = true;
context.AuditRemark = "enjoy your vacation!";
}
else
{
}
}
}
public class Manager : AbstractAuditor
{
public override void Audit(ApplyContext context)
{
Console.WriteLine("這里是經理 {0} 審批", this.Name);
if (context.Hour <= 32)
{
context.AuditResult = true;
context.AuditRemark = "enjoy your vacation!";
}
else
{
}
}
}
public class Chif : AbstractAuditor
{
public override void Audit(ApplyContext context)
{
Console.WriteLine("這里是總監 {0} 審批", this.Name);
if (context.Hour <= 64)
{
context.AuditResult = true;
context.AuditRemark = "enjoy your vacation!";
}
else
{
}
}
}
public class CEO : AbstractAuditor
{
public override void Audit(ApplyContext context)
{
Console.WriteLine("這里是CEO {0} 審批", this.Name);
if (context.Hour <= 128)
{
context.AuditResult = true;
context.AuditRemark = "enjoy your vacation!";
}
else
{
}
}
}
③上端呼叫
AbstractAuditor pm = new PM()
{
Name = "a"
};
pm.Audit(context);
if (!context.AuditResult)
{
AbstractAuditor charge = new Charge()
{
Name = "b"
};
charge.Audit(context);
if (!context.AuditResult)
{
AbstractAuditor manager = new Manager()
{
Name = "c"
};
manager.Audit(context);
if (!context.AuditResult)
{
AbstractAuditor chif = new Chif()
{
Name = "d"
};
chif.Audit(context);
if (!context.AuditResult)
{
AbstractAuditor ceo = new CEO()
{
Name = "e"
};
ceo.Audit(context);
}
}
}
}
分析: 初步有了oop思想,考慮物件,轉移了審批邏輯,
請假條+主管+經理---封裝業務邏輯,繼承復用代碼,還有多型 ,
但是也是個代碼搬運工,也是個翻譯機+OOP思想,因為沒有自己的思考
這只是翻譯,表面上正確,實際上不可用的代碼,因為不可能越級請假
開發不僅是搬運,還得有思想,
3:高級程式員
①實體類改造
public class PM : AbstractAuditor
{
public override void Audit(ApplyContext context)
{
Console.WriteLine("這里是專案經理 {0} 審批", this.Name);
if (context.Hour <= 8)
{
context.AuditResult = true;
context.AuditRemark = "enjoy your vacation!";
}
else
{
AbstractAuditor charge = new Charge()
{
Name = "b"
};
charge.Audit(context);
}
}
}
public class Charge: AbstractAuditor
{
public override void Audit(ApplyContext context)
{
Console.WriteLine("這里是主管 {0} 審批", this.Name);
if (context.Hour <= 16)
{
context.AuditResult = true;
context.AuditRemark = "enjoy your vacation!";
}
else
{
AbstractAuditor manager = new Manager()
{
Name = "c"
};
manager.Audit(context);
}
}
}
public class Manager : AbstractAuditor
{
public override void Audit(ApplyContext context)
{
Console.WriteLine("這里是經理 {0} 審批", this.Name);
if (context.Hour <= 32)
{
context.AuditResult = true;
context.AuditRemark = "enjoy your vacation!";
}
else
{
AbstractAuditor chif = new Chif()
{
Name = "d"
};
chif.Audit(context);
}
}
}
public class Chif : AbstractAuditor
{
public override void Audit(ApplyContext context)
{
Console.WriteLine("這里是總監 {0} 審批", this.Name);
if (context.Hour <= 64)
{
context.AuditResult = true;
context.AuditRemark = "enjoy your vacation!";
}
else
{
AbstractAuditor ceo = new CEO()
{
Name = "e"
};
ceo.Audit(context);
}
}
}
public class CEO : AbstractAuditor
{
public override void Audit(ApplyContext context)
{
Console.WriteLine("這里是CEO {0} 審批", this.Name);
if (context.Hour <= 128)
{
context.AuditResult = true;
context.AuditRemark = "enjoy your vacation!";
}
else
{
}
}
}
②上端呼叫
AbstractAuditor pm = new PM()
{
Name = "a"
};
pm.Audit(context);
分析:
程式員開始有思考就進入高級了,申請應該是自動流轉,物件的職責要增加,
轉移了申請提交邏輯,
但是假如審批流程變化了,組織架構發生變化,需要修改代碼,缺乏前瞻性,
4:優秀的高級程式員
①審批者抽象父類添加設定下個流程節點的職責
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);
}
}
}
②物件實體類改造
public class PM : AbstractAuditor
{
public override void Audit(ApplyContext context)
{
Console.WriteLine("這里是專案經理 {0} 審批", this.Name);
if (context.Hour <= 8)
{
context.AuditResult = true;
context.AuditRemark = "enjoy your vacation!";
}
else
{
base.AuditNext(context);
}
}
}
public class Charge: AbstractAuditor
{
public override void Audit(ApplyContext context)
{
Console.WriteLine("這里是主管 {0} 審批", this.Name);
if (context.Hour <= 16)
{
context.AuditResult = true;
context.AuditRemark = "enjoy your vacation!";
}
else
{
base.AuditNext(context);
}
}
}
public class Manager : AbstractAuditor
{
public override void Audit(ApplyContext context)
{
Console.WriteLine("這里是經理 {0} 審批", this.Name);
if (context.Hour <= 32)
{
context.AuditResult = true;
context.AuditRemark = "enjoy your vacation!";
}
else
{
base.AuditNext(context);
}
}
}
public class Chif : AbstractAuditor
{
public override void Audit(ApplyContext context)
{
Console.WriteLine("這里是總監 {0} 審批", this.Name);
if (context.Hour <= 64)
{
context.AuditResult = true;
context.AuditRemark = "enjoy your vacation!";
}
else
{
base.AuditNext(context);
}
}
}
public class CEO : AbstractAuditor
{
public override void Audit(ApplyContext context)
{
Console.WriteLine("這里是CEO {0} 審批", this.Name);
if (context.Hour <= 128)
{
context.AuditResult = true;
context.AuditRemark = "enjoy your vacation!";
}
else
{
base.AuditNext(context);
}
}
}
③上端呼叫指定流程節點
AbstractAuditor pm = new PM()
{
Name = "a"
};
AbstractAuditor charge = new Charge()
{
Name = "b"
};
AbstractAuditor manager = new Manager()
{
Name = "c"
};
AbstractAuditor chif = new Chif()
{
Name = "d"
};
AbstractAuditor ceo = new CEO()
{
Name = "e"
};
pm.SetNext(charge);
charge.SetNext(manager);
manager.SetNext(chif);
chif.SetNext(ceo);
pm.Audit(context);
分析:流程就可以變化了,能更好的應對業務的升級變遷,遵循開閉原則,
如果覺得上面設定流程部分負責,可以封裝一下,采用反射+組態檔實作擴展,
5:架構師
架構師首先是有著豐富的程式設計經驗,然后還需要能融匯貫通,能高度抽象業務,然后恰如其分的去應用各種程式設計思想,解決的問題不再是面向具體業務,而是面向框架,
4:責任鏈模式的優缺點
1:優點
①降低耦合
職責鏈模式使得一個物件無須知道是其他哪一個物件處理請求,物件僅需知道請求會被處理即可,接收者和發送者都沒有對方明確資訊,且鏈中物件不需要知道鏈的結構,由客戶端負責鏈的創建,降低了系統耦合度,
②簡化物件連接
請求處理物件僅需維持一個指向其后繼者的參考,而不需要維持它對所有候選處理者的參考,可簡化物件的相互連接,
③靈活的職責鏈
可以在運行時對鏈進行動態增加或者修改,
④符合OCP
系統增加一個新的具體處理者時無須修改原始碼,只需要客戶端重建職責鏈,符合OCP,
2:缺點
①請求可能得不到處理
由于一個請求沒有明確的接收者,因此請求不一定會被處理,也有可能因為職責鏈配置錯誤而得不到處理,
②性能受到影響
對于較長的職責鏈,請求的處理可能涉及多個處理物件,系統性能會受到一定影響,而且代碼除錯時可能不方便,
③死回圈
如果職責鏈不當,可能會導致死回圈呼叫,
5:適應場景
①有多個物件可以處理同一個請求,具體哪個物件處理該請求待運行時刻再確定,客戶端只需將請求提交到鏈上,而無須關心請求的處理物件是誰以及它是如何處理的,
②在不明確指定接收者的情況下,向多個物件的一個提交一個請求,
③可動態指定一組物件處理請求,客戶端可以動態創建職責鏈來處理請求,還可以改變鏈中處理請求以及處理者之間的先后次序,
6:應用實體
人事行政審核
財務請款審核
7:ASP.NET 管道模型

請求進入ASP.NET 作業行程后,由行程創建HttpWorkRequest 物件,封裝此次請求有關的所有資訊,然后進入HttpRuntime 類進行進一步的處理,HttpRuntime 通過請求資訊創建HttpContext 背景關系物件,此物件將貫穿整個管道,直到回應結束,同時創建或從應用程式池里初始化一個HttpApplication物件,由此物件開始處理之前注冊的多個HttpModule,之后呼叫HandlerFactory 創建Handler處理程式,最終處理此次請求內容,生存回應回傳,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/301479.html
標籤:其他
上一篇:WebSocket服務端訊息推送
