第二十章 Caché 設計模式 職責鏈模式
定義
使多個對象都有機會處理請求,從而避免請求發送者與接收者之間的耦合關係。將這個對象連成一條鏈,並沿着這條鏈傳遞該請求,知道有一個對象處理它爲止。
優點
- 請求者和處理者關係解耦,提高代碼靈活性。
- 當客戶提交一個請求時,請求是沿着鏈傳遞直至有一個ConcreteHandler對象負責處理它。
- 隨時地增加或修改處理一個請求的結構。增強了對象指派職責的靈活性。
- 接收者和發送者都沒有對象的明確信息,且鏈中的對象自己也並不知道鏈的結構,結果是職責鏈可簡化對象的相互連接,它們僅需保持一個指向其後繼承者的引用,而不需保持它所有的候選接受者的引用。
缺點
- 對處理者遍歷,弱處理者太多,會影響性能,特別在遞歸處理中尤其需要注意。
結構圖
描述
申請人,申請請假或加薪,隨着申請權限不同,扭轉不同管理者。
完整示例
請求類
Class PHA.YX.Design.Chain.Request Extends %RegisteredObject
{
Property requestType As %String;
Method requestTypeGet() As %String [ ServerOnly = 1 ]
{
Quit i%requestType
}
Method requestTypeSet(Arg As %String) As %Status [ ServerOnly = 1 ]
{
s i%requestType = Arg
Quit $$$OK
}
Property requestContent As %String;
Method requestContentGet() As %String [ ServerOnly = 1 ]
{
Quit i%requestContent
}
Method requestContentSet(Arg As %String) As %Status [ ServerOnly = 1 ]
{
s i%requestContent = Arg
Quit $$$OK
}
Property number As %String;
Method numberGet() As %String [ ServerOnly = 1 ]
{
Quit i%number
}
Method numberSet(Arg As %String) As %Status [ ServerOnly = 1 ]
{
s i%number = Arg
Quit $$$OK
}
}
抽象責任類
Class PHA.YX.Design.Chain.Manager Extends %RegisteredObject
{
Property name As %String;
Property superior As Manager;
Method %OnNew(name As %String) As %Status [ Private, ServerOnly = 1 ]
{
s ..name = name
Quit $$$OK
}
Method SetSuperior(superior As Manager)
{
s ..superior = superior
}
Method RequertApplications(request As Request) [ Abstract ]
{
}
}
實現責任類
Class PHA.YX.Design.Chain.CommonManager Extends Manager
{
Method %OnNew(name As %String) As %Status [ Private, ServerOnly = 1 ]
{
d ##super(name)
Quit $$$OK
}
Method RequertApplications(request As Request)
{
i (request.requestTypeGet() = "請假") && (request.numberGet() <= 2) d
.w ..name _ ":" _ request.requestContentGet() _ "數量" _ request.numberGet() _ "被批准",!
e d
.i ..superior '= "" d
..d ..superior.RequertApplications(request)
}
}
Class PHA.YX.Design.Chain.MajorManager Extends Manager
{
Method %OnNew(name As %String) As %Status [ Private, ServerOnly = 1 ]
{
d ##super(name)
Quit $$$OK
}
Method RequertApplications(request As Request)
{
i (request.requestTypeGet() = "請假") && (request.numberGet() <= 5) d
.w ..name _ ":" _ request.requestContentGet() _ "數量" _ request.numberGet() _ "被批准",!
e d
.i ..superior '= "" d
..d ..superior.RequertApplications(request)
}
}
Class PHA.YX.Design.Chain.GeneralManager Extends Manager
{
Method %OnNew(name As %String) As %Status [ Private, ServerOnly = 1 ]
{
d ##super(name)
Quit $$$OK
}
Method RequertApplications(request As Request)
{
i (request.requestTypeGet() = "請假") d
.w ..name _ ":" _ request.requestContentGet() _ " 數量" _ request.numberGet() _ "被批准",!
e i (request.requestTypeGet() = "加薪") && (request.numberGet() <=500) d
.w ..name _ ":" _ request.requestContentGet() _ " 數量" _ request.numberGet() _ "被批准",!
e i (request.requestTypeGet() = "加薪") && (request.numberGet() >500) d
.w ..name _ ":" _ request.requestContentGet() _ " 數量" _ request.numberGet() _ "再說吧",!
}
}
調用
/// d ##class(PHA.YX.Design.Program).Chain()
ClassMethod Chain()
{
s zz = ##class(PHA.YX.Design.Chain.CommonManager).%New("周總")
s sz = ##class(PHA.YX.Design.Chain.MajorManager).%New("蘇總")
s hz = ##class(PHA.YX.Design.Chain.GeneralManager).%New("韓總")
d zz.SetSuperior(sz)
d sz.SetSuperior(hz)
s request = ##class(PHA.YX.Design.Chain.Request).%New()
d request.numberSet(1)
d request.requestContentSet("丁竑瑩請假")
d request.requestTypeSet("請假")
d zz.RequertApplications(request)
s request1 = ##class(PHA.YX.Design.Chain.Request).%New()
d request1.numberSet(4)
d request1.requestContentSet("小馬哥請假")
d request1.requestTypeSet("請假")
d zz.RequertApplications(request1)
s request2 = ##class(PHA.YX.Design.Chain.Request).%New()
d request2.numberSet(500)
d request2.requestContentSet("姚鑫請求加薪")
d request2.requestTypeSet("加薪")
d zz.RequertApplications(request2)
s request3 = ##class(PHA.YX.Design.Chain.Request).%New()
d request3.numberSet(1000)
d request3.requestContentSet("姚鑫請求加薪")
d request3.requestTypeSet("加薪")
d zz.RequertApplications(request3)
}
DHC-APP>d ##class(PHA.YX.Design.Program).Chain()
周總:丁竑瑩請假數量1被批准
蘇總:小馬哥請假數量4被批准
韓總:姚鑫請求加薪 數量500被批准
韓總:姚鑫請求加薪 數量1000再說吧
思考
英雄聯盟,黑鐵,青銅,白銀,黃金,鉑金,鑽石,大師,王者。請求者爲對應級別纔可以匹配,否則扭轉。