代码GitHub:github.com/lanjie6/Des…
责任链模式
- 责任链模式,又叫职责链模式,将能够处理同一类请求的对象连成一条链,然后将请求的发送者和接收者进行了解耦。
- 责任链模式会将所提交的请求沿着接收者的链进行传递,链上的对象逐个判断是否有能力处理该请求,如果能处理则处理,如果不能处理就传递给接收者链上的下一个对象,以此类推。
进一步阐述:责任链模式属于行为型模式,每个接收者都包含对另一个接收者的引用,以此形成接收者的链。
责任链模式包含三种角色:
- Handler(抽象处理者):只能是一个抽象类,它定义了一个处理请求的方法, 同时包含另外 Handler的引用。
- ConcreteHandler(具体处理者):继承了抽象处理者,负责处理它能处理的请求,并可以访问它的下一个处理者,如果能处理当前请求则处理,如果不能处理就将该请求交给下一个处理者去处理,从而形成一个责任链。
- Request (请求对象):含有很多需要处理的属性,表示一个需要被处理的请求。
案例:税务系统的收税逻辑:月收入<=5000时不纳税;5000<月收入<=8000时,超过5000部分缴纳5%的税费;8000<月收入<=15000时,在缴纳超出5000部分的税费后超过8000部分缴纳10%的税费;15000<月收入<=30000时,在缴纳超出5000部分和超出8000部分的税费后超过15000部分缴纳15%的税费。税费管理服务TaxationService抽象类就是抽象处理者,税费计算请求对象TaxationCalculateRequest类就是请求对象,其他处理税费的类都是具体的处理者。PS:为了方便阅读,案例中的代码我们暂不考虑小数计算的精度问题
UML类图:
客户端Client:
/**
* 使用责任链模式的客户端
*/
public class Client {
public static void main(String[] args) {
//创建各个税费计算对象
TaxationService taxationService1 = new LessFiveThousandTaxationService();
TaxationService taxationService2 = new LessEightThousandTaxationService();
TaxationService taxationService3 = new LessFifteenThousandTaxationService();
TaxationService taxationService4 = new LessThirtyThousandTaxationService();
//构建计算的责任链
taxationService1.setTaxationService(taxationService2);
taxationService2.setTaxationService(taxationService3);
taxationService3.setTaxationService(taxationService4);
//计算月收入4500的税费
TaxationCalculateRequest request = new TaxationCalculateRequest();
request.setMonthlyIncome(4500);
double taxation = taxationService1.calculateTaxation(request);
System.out.println("月收入4500元应该缴纳的税费是:" + taxation);
//计算月收入7500的税费
request.setMonthlyIncome(7500);
taxation = taxationService1.calculateTaxation(request);
System.out.println("月收入7500元应该缴纳的税费是:" + taxation);
//计算月收入11000的税费
request.setMonthlyIncome(11000);
taxation = taxationService1.calculateTaxation(request);
System.out.println("月收入11000元应该缴纳的税费是:" + taxation);
//计算月收入19000的税费
request.setMonthlyIncome(19000);
taxation = taxationService1.calculateTaxation(request);
System.out.println("月收入19000元应该缴纳的税费是:" + taxation);
}
}
税费管理服务TaxationService抽象类:
/**
* 税费管理服务(抽象处理者)
*/
public abstract class TaxationService {
/*
* 持有一个自己类型的引用也就是持有下一个处理者
*/
protected TaxationService taxationService;
/**
* 也就是setNext方法
*/
public void setTaxationService(TaxationService taxationService) {
this.taxationService = taxationService;
}
/**
* 计算税费的方法
*
* @param request 税费请求对象
* @return 应缴纳的税费
*/
public abstract double calculateTaxation(TaxationCalculateRequest request);
}
5000元及以下税费计算服务LessFiveThousandTaxationService类:
/**
* 5000元及以下税费计算服务(具体处理者)
*/
public class LessFiveThousandTaxationService extends TaxationService {
/**
* 计算税费的方法
*
* @param request 税费请求对象
* @return 应缴纳的税费
*/
public double calculateTaxation(TaxationCalculateRequest request) {
if (request.getMonthlyIncome() <= 5000) {
return 0.0;
}
return taxationService.calculateTaxation(request);
}
}
8000元及以下税费计算服务LessEightThousandTaxationService类:
/**
* 8000元及以下税费计算服务(具体处理者)
*/
public class LessEightThousandTaxationService extends TaxationService {
/**
* 计算税费的方法
*
* @param request 税费请求对象
* @return 应缴纳的税费
*/
public double calculateTaxation(TaxationCalculateRequest request) {
double monthlyIncome = request.getMonthlyIncome();
if (monthlyIncome <= 8000) {
return request.getBaseTaxation() + (monthlyIncome - 5000) * 0.05;
}
request.setBaseTaxation((8000 - 5000) * 0.05);
return taxationService.calculateTaxation(request);
}
}
15000元及以下税费计算服务LessFifteenThousandTaxationService类:
/**
* 15000元及以下税费计算服务(具体处理者)
*/
public class LessFifteenThousandTaxationService extends TaxationService {
/**
* 计算税费的方法
*
* @param request 税费请求对象
* @return 应缴纳的税费
*/
public double calculateTaxation(TaxationCalculateRequest request) {
double monthlyIncome = request.getMonthlyIncome();
if (monthlyIncome <= 15000) {
return request.getBaseTaxation() + (monthlyIncome - 8000) * 0.1;
}
request.setBaseTaxation(request.getBaseTaxation() + (15000 - 8000) * 0.1);
return taxationService.calculateTaxation(request);
}
}
30000元及以下税费计算服务LessThirtyThousandTaxationService类:
/**
* 30000元及以下税费计算服务(具体处理者)
*/
public class LessThirtyThousandTaxationService extends TaxationService {
/**
* 计算税费的方法
*
* @param request 税费请求对象
* @return 应缴纳的税费
*/
public double calculateTaxation(TaxationCalculateRequest request) {
double monthlyIncome = request.getMonthlyIncome();
if (monthlyIncome <= 30000) {
return request.getBaseTaxation() + (monthlyIncome - 15000) * 0.15;
}
request.setBaseTaxation(request.getBaseTaxation() + (30000 - 15000) * 0.15);
return taxationService.calculateTaxation(request);
}
}
税费计算请求对象TaxationCalculateRequest类:
/**
* 税费计算请求对象(请求对象)
*/
public class TaxationCalculateRequest {
/*
* 月收入
*/
private double monthlyIncome;
/*
* 基础税费
*/
private double baseTaxation;
public double getBaseTaxation() {
return baseTaxation;
}
public void setBaseTaxation(double baseTaxation) {
this.baseTaxation = baseTaxation;
}
public double getMonthlyIncome() {
return monthlyIncome;
}
public void setMonthlyIncome(double monthlyIncome) {
this.monthlyIncome = monthlyIncome;
}
}
运行结果:
总结:
- 将请求和处理分开,实现解耦,提高了系统的灵活性遵守了单一职能原则。
- 简化了请求对象,使请求对象不需要知道链的结构,遵守了迪米特法则。
- 如果责任链比较长,那么系统性能会受到很大影响,因此需控制链中最大节点数量,一般通过在Handler 中设置一个最大节点数量,在setNext()方法中判断是否已经超过阀值,超过则不允许该链建立,避免出现超长链而影响系统性能的情况发生。
- 调试不方便,采用了类似递归的方式,调试时逻辑可能比较复杂必须跟着链去一个一个地寻找出错点。
典型运用场景举例:
- OA系统中的请假、文件审批等审批流程。
- 学校教务系统中的奖学金审批、处分表扬审批。
- 电商系统中的多重打折和优惠叠加计算折后价格的场景。
设计模式相关文章
- 【Java设计模式】设计模式七大基本原则(一)
- 【Java设计模式】创建型设计模式-单例模式(二)
- 【Java设计模式】创建型设计模式-工厂模式(三)
- 【Java设计模式】创建型设计模式-建造者模式(四)
- 【Java设计模式】创建型设计模式-原型模式(五)
- 【Java设计模式】结构型设计模式-适配器模式(六)
- 【Java设计模式】结构型设计模式-装饰者模式(七)
- 【Java设计模式】结构型设计模式-门面模式(八)
- 【Java设计模式】结构型设计模式-桥接模式(九)
- 【Java设计模式】结构型设计模式-代理模式(十)
- 【Java设计模式】结构型设计模式-享元模式(十一)
- 【Java设计模式】结构型设计模式-组合模式(十二)
- 【Java设计模式】行为型设计模式-策略模式(十三)
- 【Java设计模式】行为型设计模式-模板方法模式(十四)
- 【Java设计模式】行为型设计模式-观察者模式(十五)
- 【Java设计模式】行为型设计模式-责任链模式(十六)
- 【Java设计模式】行为型设计模式-委派模式(十七)
- 【Java设计模式】行为型设计模式-状态模式(十八)
- 【Java设计模式】行为型设计模式-中介者模式(十九)
- 【Java设计模式】行为型设计模式-迭代器模式(二十)
- 【Java设计模式】行为型设计模式-访问者模式(二十一)
- 【Java设计模式】行为型设计模式-备忘录模式(二十二)
- 【Java设计模式】行为型设计模式-解释器模式(二十三)