设计模式-行为型-责任链模式
责任链模式再生活中随处可见,比如工厂的生产链,再每个环节拿到原料进行加工生产,质检合格后投入到下一环节,这就是一个责任链模式。
责任链模式
将请求沿着处理者链进行发送。 收到请求后, 每个处理者均可对请求进行处理, 或将其传递给链上的下个处理者。
一、责任链模式
将流程中的每个节点都看作一个对象,每个节点处理的请求都不相同,且节点内部进行下一节点的选择,并传递消息,直到请求被处理为止。比如,.net Core 的Middleware 中间件,闯关游戏。
二、应用场景
- 多个对象可以处理同一请求,但具体由那个对象处理则再运行时动态决定。
- 在不明确指定接收者的情况下,向多个对象中的一个提交请求。
- 可动态指定一组对象处理请求。
三、角色
- 抽象处理者(Handler):定义一个请求处理的方法,并维护下一个处理节点Handler对象的引用。
- 基础处理者(Base Handler):可省略,抽象处理的基础实现,可以被具体处理者进行重写。
- 具体处理者(ConcreteHandler):对请求进行处理。可独立实现也可以重写基础处理者。
注意:基础处理者可以省略,直接由具体处理者实现抽象处理者。
四、使用步骤
1.创建抽象处理者
代码如下(示例):
public interface IGameHandler
{
public IGameHandler PlayNextGame(IGameHandler gameHandler);
IGameHandler SetNextHandler(IGameHandler gameHandler1);
}
2.基础处理者
代码如下(示例):
public class baseHandler : IGameHandler
{
public IGameHandler _nextHandler;
public virtual IGameHandler PlayNextGame(IGameHandler gameHandler)
{
Console.WriteLine($"Setp 0:baseHandler{this.GetType().ToString()}");
return this._nextHandler.SetNextHandler(gameHandler);
}
public IGameHandler SetNextHandler(IGameHandler gameHandler1)
{
_nextHandler = gameHandler1;
return _nextHandler.PlayNextGame(gameHandler1);
}
}
3.详细处理者
代码如下(示例):
public class GameHandler1 : baseHandler
{
public override IGameHandler PlayNextGame(IGameHandler gameHandler)
{
Console.WriteLine($"Setp 1:GameHandler1{this.GetType().ToString()}");
return _nextHandler;
}
}
public class GameHandler2 : baseHandler
{
public override IGameHandler PlayNextGame(IGameHandler gameHandler)
{
Console.WriteLine($"Setp 2:GameHandler2{this.GetType().ToString()}");
return gameHandler;
}
}
4.调用者
代码如下(示例):
public class GameClient
{
public void doRunGame() {
var gh1=new GameHandler1();
var gh2 = new GameHandler2();
gh1.PlayNextGame(gh2);
gh1.SetNextHandler(gh2);
}
}
5.输出
Setp 1:GameHandler1Conceptual.game.GameHandler1
Setp 2:GameHandler2Conceptual.game.GameHandler2
总结
优点:
- 将请求与处理解耦
- 节点对象只需要关注自己所在节点的操作即可,其他操作一律交给下一节点,
- 链路结构灵活,可以通过该百年链路结构动态的新增或删减责任
- 易于扩展新的请求节点,复合开闭原则。
缺点:
- 责任链太长或者处理时间过长,会影响整体性能
- 如果节点对象存在循环引用,会造成死循环,导致系统崩溃。