概念
责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链,使多个对象都有机会处理同一个请求。这种模式中请求的发送者和接收者,以及接收者间都是解耦的。
应用
- 过滤器
- 复杂的ifelse判断,选用于判断条件和内容都复杂,或者内容复杂的情况
- OA系统中的审批
例子
之前看到这个模式感觉很适合现在项目中运输路线的规划,所以写了一个小demo
背景:假设根据实际运输的距离来判断生成运输路线使用哪种方案,距离小于10千米,不用调拔,10千米<距离<20千米,一级调拔,20千米<距离<30千米,二级调拔(当初实际情况是很复杂的)
1.创建一个请求对象
public class TranslineQueryParam {
private Integer distance;
public Integer getDistance() {
return distance;
}
public void setDistance(Integer distance) {
this.distance = distance;
}
}
2.创建一个接收对象
public class TranslineResult {
private String info;
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
}
3.创建一个Handler
public abstract class TranslineQueryHandler {
//这个变量主要是给各个Handler起个名字,方便调试
private String name;
//这个字段一定要有,指定下一处理者
private TranslineQueryHandler nextTranslineQueryHandler;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public TranslineQueryHandler(String name){
this.name=name;
}
public TranslineQueryHandler getNextTranslineQueryHandler() {
return nextTranslineQueryHandler;
}
//给当前对象指定下一处理人,并返回【下一处理人】
public TranslineQueryHandler setNextTranslineQueryHandler(TranslineQueryHandler next) {
this.nextTranslineQueryHandler = next;
System.out.println("-----处理人------"+this+"-----的下一处理人-----"+next);
return next;
}
public String toString() { // 显示字符串
return "[" + name + "]";
}
//抽象方法deal:用于处理请求,所有处理人都要根据自身条件重写此方法
public abstract TranslineResult deal(TranslineQueryParam translineQueryParam);
//核心方法doChain:如果当前TranslineQueryHandler可以解决,就解决,如果不行,就调此方法交给next去解决
protected void doChain(TranslineQueryParam translineQueryParam){
if(this.nextTranslineQueryHandler != null){
this.nextTranslineQueryHandler.deal(translineQueryParam);
}
}
}
4.创建责任链中的三个对象
对象一:不需要调拔
public class NoNeedWarehousesCross extends TranslineQueryHandler{
public NoNeedWarehousesCross(String name) {
super(name);
}
@Override
public TranslineResult deal(TranslineQueryParam translineQueryParam) {
TranslineResult translineResult =new TranslineResult();
if(translineQueryParam.getDistance()<10){
System.out.println("--------------不需要调拔就可以找到运输路线-----------------------");
translineResult.setInfo("--------------不需要调拔就可以找到运输路线-----------------------");
}else {
System.out.println("--------------进入调拔逻辑-----------------------");
translineResult.setInfo("--------------进入调拔逻辑-----------------------");
this.doChain(translineQueryParam);
}
return translineResult;
}
}
对象二:一级调拔
public class OneTimeWarehousesCross extends TranslineQueryHandler{
public OneTimeWarehousesCross(String name) {
super(name);
}
@Override
public TranslineResult deal(TranslineQueryParam translineQueryParam) {
TranslineResult translineResult = new TranslineResult();
if(translineQueryParam.getDistance()<20){
System.out.println("--------------一级调拔可以找到运输路线-----------------------");
translineResult.setInfo("--------------一级调拔可以找到运输路线-----------------------");
}else {
System.out.println("--------------进入二级调拔-----------------------");
translineResult.setInfo("--------------进入二级调拔-----------------------");
this.doChain(translineQueryParam);
}
return translineResult;
}
}
对象三:二级调拔
public class TwoTimeWarehousesCross extends TranslineQueryHandler{
public TwoTimeWarehousesCross(String name) {
super(name);
}
@Override
public TranslineResult deal(TranslineQueryParam translineQueryParam) {
TranslineResult translineResult = new TranslineResult();
if(translineQueryParam.getDistance()<30){
System.out.println("--------------两级调拔可以找到运输路线-----------------------");
translineResult.setInfo("--------------两级调拔可以找到运输路线-----------------------");
}else {
System.out.println("--------------找不到运输路线-----------------------");
translineResult.setInfo("--------------找不到运输路线-----------------------");
this.doChain(translineQueryParam);
}
return translineResult;
}
}
5.将这些对象组装并测试
public class TranslinesCalculate {
public static void main(String[] args) {
NoNeedWarehousesCross noNeedWarehousesCross = new NoNeedWarehousesCross("no");
OneTimeWarehousesCross oneTimeWarehousesCross = new OneTimeWarehousesCross("one");
TwoTimeWarehousesCross twoTimeWarehousesCross = new TwoTimeWarehousesCross("two");
//组装责任链
noNeedWarehousesCross.setNextTranslineQueryHandler(oneTimeWarehousesCross).setNextTranslineQueryHandler(twoTimeWarehousesCross);
//链头部开始执行
TranslineQueryParam translineQueryParam = new TranslineQueryParam();
translineQueryParam.setDistance(18);
noNeedWarehousesCross.deal(translineQueryParam);
}
}
6.结果