设计模式----责任链模式

概述

某个请求需要多个对象进行处理,从而避免请求的发送者和接收之间的耦合关系。将这些对象连成一条链子,并沿着这条链子传递该请求,直到有对象处理它为止。

涉及角色

  • Handler
    抽象处理者角色:定义出一个处理请求的接口。通常由一个Java抽象类或者Java接口实现。
  • ConcreteHandler
    具体处理者角色:具体处理者接受到请求后,可以选择将该请求处理掉,或者将请求传给下一个处理者。因此,每个具体处理者需要保存下一个处理者的引用,以便把请求传递下去

UML

这里写图片描述

使用场景

  • 有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。
  • 在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
  • 可动态指定一组对象处理请求

优点

  • 降低耦合度。它将请求的发送者和接收者解耦。
  • 简化了对象。使得对象不需要知道链的结构。
  • 增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。
  • 增加新的请求处理类很方便。

缺点

  • 不能保证请求一定被接收。
  • 系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。
  • 可能不容易观察运行时的特征,有碍于除错

代码示例

报销审批流程是一个很好的例子,超过多少金额需要哪个级别的审批,比如加班交通费报销,不超过3k需要leader和经理审批,超过3k需要总监再次审批才能报销……

定义处理请求的方法

package com.designpattern.responsibility;

public interface Handler {
    //处理请求的方法
    public void handleRequest(); 
}

定义抽象处理者角色

package com.designpattern.responsibility;

public abstract class AbstractHandler {
    //持有后继的责任对象
    private Handler handler;  

    public Handler getHandler() {  
        return handler;  
    }  

    public void setHandler(Handler handler) {  
        this.handler = handler;  
    }  
}

定义具体处理者角色。继承抽象类并实现具体的处理请求的方法

package com.designpattern.responsibility;

//核心类,实例化后生成一系列相互持有的对象,构成一条链
public class ConcreteHandler extends AbstractHandler implements Handler {
    private String role;  
    //为方便演示,这里的构造函数传入参数标识代替多个具体类
    public ConcreteHandler(String role) {  
        this.role = role;  
    }  

    //覆写具体处理请求的方法
    @Override  
    public void handleRequest() {  
        System.out.println(role+" 审批!");  
        if(getHandler()!=null){  
            getHandler().handleRequest();  
        }  
    }  
}
package com.designpattern.responsibility;

public class TestMain {
    public static void main(String[] args) {  
        ConcreteHandler leader = new ConcreteHandler("直接领导");  
        ConcreteHandler manager = new ConcreteHandler("经理");  
        ConcreteHandler chief = new ConcreteHandler("总监"); 
        ConcreteHandler accountant = new ConcreteHandler("财务");  

        double fee= Math.random()*9999;

        System.err.println("加班费:"+fee);

        if (fee<=3000) {
            leader.setHandler(manager);
            manager.setHandler(accountant);
        } else {
            leader.setHandler(manager);
            manager.setHandler(chief);  
            chief.setHandler(accountant);
        }

        leader.handleRequest("加班交通费报销:");  
    }  
}

运行结果:

加班费:3139.0867555809655
加班交通费报销: 直接领导 审批!
加班交通费报销: 经理 审批!
加班交通费报销: 总监 审批!
加班交通费报销: 财务 审批!


加班费:1624.8882151886996
加班交通费报销: 直接领导 审批!
加班交通费报销: 经理 审批!
加班交通费报销: 财务 审批!

逻辑非常简单:只要有下家,就传给下家处理;如果没有下家,就自行处理。

猜你喜欢

转载自blog.csdn.net/yue530tomtom/article/details/79855652