责任链模式(Chain)
目录
一、概念:
使多个对象都有处理请求的机会,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象串成一条链,并沿着这条链一直传递该请求,直到有对象处理它为止。责任链模式的重点在“链上”,由一条链去处理相似的请求,在链中决定谁来处理这个请求,并返回相应的结果。
通俗:我们可以将多个对象组成一条职责链,然后按照它们在职责链上的顺序一个一个地找出到底应该谁来负责处理。
角色
- 抽象处理者(Handler) :定义一个处理请求的接口。关联自身类型的变量。
- 具体处理者(Concrete Handler): 实现 抽象处理者中的处理方法,处理请求或者传递给下个处理对象。
- 客户端(Client):设置处理链,并调用。
优点
- 请求的发送者和处理解耦。
- 可以根据不同的需求进行动态的组合。
- 增强了给对象指派职责的灵活性,可以很方便的修改、增加、减少责任链中的元素。
缺点
影响性能。当责任链太长,如果只有最后一个可以处理,就会创建许多处理对象并且请求会在它们之间传递。
二、代码结构
1.抽象代码结构
class ChainClient
{
public void Run()
{
Handler h1 = new ConcreteHandler1();
Handler h2 = new ConcreteHandler2();
Handler h3 = new ConcreteHandler3();
h1.SetSuccessor(h2);
h2.SetSuccessor(h3);
int[] requests = { 2, 5, 14, 22, 18, 3, 27, 20 };
foreach (int request in requests)
{
h1.HandleRequest(request);
}
Console.ReadKey();
}
}
abstract class Handler
{
protected Handler successor;
public void SetSuccessor(Handler successor)
{
this.successor = successor;
}
public abstract void HandleRequest(int request);
}
class ConcreteHandler1 : Handler
{
public override void HandleRequest(int request)
{
if (request >= 0 && request < 10)
{
Console.WriteLine("{0} handled request {1}",this.GetType().Name, request);
}
else if (successor != null)
{
successor.HandleRequest(request);
}
}
}
class ConcreteHandler2 : Handler
{
public override void HandleRequest(int request)
{
if (request >= 10 && request < 20)
{
Console.WriteLine("{0} handled request {1}",this.GetType().Name, request);
}
else if (successor != null)
{
successor.HandleRequest(request);
}
}
}
class ConcreteHandler3 : Handler
{
public override void HandleRequest(int request)
{
if (request >= 20 && request < 30)
{
Console.WriteLine("{0} handled request {1}",this.GetType().Name, request);
}
else if (successor != null)
{
successor.HandleRequest(request);
}
}
}
2.实际案例
在公司上班,遇到突发事件都需要请假,而请假根据天数不同需要不同的主管来同意我们的请求,比如我们要请1-3天的假期一级主管就可以直接同意,不需要再往上请求,如果是4-6天就需要二级主管同意,如果是7-10天就需要3级主管同意,大于10天需要我们的boss来同意才行。现在我们用责任链模式来模拟这个场景。
//处理者基类
public abstract class LeaveHandler {
//持有指向后继者的引用
protected LeaveHandler successor;
//设置后继者
public void setSuccessor(LeaveHandler successor) {
this.successor = successor;
}
public abstract void handleRequest(int request);
}
//一级主管
public class FirstLevelSupervisor extends LeaveHandler {
@Override
public void handleRequest(int request) {
if (request<=3){
System.out.println("一级主管已同意");
}else {
if (successor!=null){
//请请求传递给责任链的下一个处理对象处理
successor.handleRequest(request);
}
}
}
}
//二级主管
public class SecondLevelSupervisor extends LeaveHandler{
@Override
public void handleRequest(int request) {
if (4<=request&&request<=6){
System.out.println("二级主管已同意");
}else {
if (successor!=null){
//请请求传递给责任链的下一个处理对象处理
successor.handleRequest(request);
}
}
}
}
//三级主管
public class ThirdLevelSupervisor extends LeaveHandler {
@Override
public void handleRequest(int request) {
if (7<=request&&request<=10){
System.out.println("三级主管已同意");
}else {
if (successor!=null){
//请请求传递给责任链的下一个处理对象处理
successor.handleRequest(request);
}
}
}
}
//Boss
public class Boss extends LeaveHandler {
@Override
public void handleRequest(int request) {
System.out.println("Boss已同意");
}
}
//测试
public static void main(String[] args) {
LeaveHandler firstLevelSupervisor=new FirstLevelSupervisor();
LeaveHandler secondLevelSupervisor=new SecondLevelSupervisor();
LeaveHandler thirdLevelSupervisor=new ThirdLevelSupervisor();
LeaveHandler boss=new Boss();
//形成责任链
firstLevelSupervisor.setSuccessor(secondLevelSupervisor);
secondLevelSupervisor.setSuccessor(thirdLevelSupervisor);
thirdLevelSupervisor.setSuccessor(boss);
//向一级主管提交7天的假期申请
firstLevelSupervisor.handleRequest(7);
}