第二十章 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再说吧
思考
英雄联盟,黑铁,青铜,白银,黄金,铂金,钻石,大师,王者。请求者为对应级别才可以匹配,否则扭转。