设计模式のChainOfResponsibilityPattern(责任链模式)----行为模式
一、产生背景
职责链模式是一种行为模式,为解除请求的发送者和接收者之间的耦合,而使多个对象都有机会处理这个请求。将这些对象连接成一条链,并沿着这条链传递该请求,直到有一个对象处理它。避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。
二、常见的场景
1、通关游戏
我们的游戏角色就是一批数据,这批数据需要经过没一个关卡的处理,每一个关卡就是责任链上的一个环节。
2、审批流程
一项请求事物,我们需要经过三级部门经理->二级部门经理->总经理->总裁 处理,每个审批流程也是责任链上的一个环节。
3、鉴权
一个用户登录,需要处理是否符合账密验证、是否授权过期、是否符合规范等
4、任务的执行
同一组数据,需要处理前日志输出、执行一、执行二、运行后日志输出
综上,责任链模式是同一个请求或者被处理对象的不同处理过程,每个处理过程偏复杂
三、实现方式
职责链模式参与者:
◊ Handler
° 定义一个处理请求的接口
° 实现后继链
◊ ConcreteHandler
° 处理其所负责的请求
° 可访问其后继者
° 如果可处理该请求,则处理;否则将该请求转发给它的后继者。
◊ Request:向链上的具体处理者对象提交请求
在职责链模式中,Request向Handler提交请求,请求在多个ConcreteHandler对象形成的对象链中被传递,请求在传递的过程中被处理。
四、实例
我们要处理的对象
public class Request { public int Level { get; set; } public string Data { get; set; }
首先定义一个接口 IRequestHandler 来表示请求处理器,其中包含两个方法:
public interface IRequestHandler { void SetNextHandler(IRequestHandler nextHandler); void HandleRequest(Request request); }
然后定义一个实现了 IRequestHandler 接口的抽象类 AbstractRequestHandler:
public abstract class AbstractRequestHandler : IRequestHandler { private IRequestHandler _nextHandler; public void SetNextHandler(IRequestHandler nextHandler) { _nextHandler = nextHandler; }
public void HandleRequest(Request request)
{
if (CanHandleRequest(request))
{
DoHandleRequest(request);
}
if (_nextHandler != null)
{
_nextHandler.HandleRequest(request);
}
}
protected abstract bool CanHandleRequest(Request request); protected abstract void DoHandleRequest(Request request); }
其中,CanHandleRequest 方法用于判断当前处理器是否能够处理该请求;DoHandleRequest 方法用于实际处理请求。
最后,定义一个继承自 AbstractRequestHandler 的具体处理器类 ConcreteRequestHandler:
public class ConcreteRequestHandler : AbstractRequestHandler { protected override bool CanHandleRequest(Request request) { // 根据具体需求判断该请求是否能够被当前处理器处理 return request.Level <= 3; } protected override void DoHandleRequest(Request request) { // 实际处理请求的代码 Console.WriteLine($"Request handled by {GetType().Name}"); } }
在程序中,可以先创建一条处理链并设置处理器:
var handler1 = new ConcreteRequestHandler1(); var handler2 = new ConcreteRequestHandler2(); var handler3 = new ConcreteRequestHandler3(); handler1.SetNextHandler(handler2); handler2.SetNextHandler(handler3);
四、设计模式分析
优点: 1、降低耦合度。它将请求的发送者和接收者解耦。 2、简化了对象。使得对象不需要知道链的结构。 3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。 4、增加新的请求处理类很方便。
缺点: 1、不能保证请求一定被接收。 2、系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。 3、可能不容易观察运行时的特征,有碍于除错