概念
责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链,使多个对象都有机会处理同一个请求。这种模式中请求的发送者和接收者,以及接收者间都是解耦的。
应用
- 过滤器
- 复杂的ifelse判断,选用于判断条件和内容都复杂,或者内容复杂的情况
- OA系统中的审批
例子
实例的背景
之前看到这个模式感觉很适合现在项目中运输路线的规划,所以写了一个小demo
背景:假设根据实际运输的距离来判断生成运输路线使用哪种方案,距离小于10千米,不用调拔,10千米<距离<20千米,一级调拔,20千米<距离<30千米,二级调拔(实际情况是是很复杂的)
实例的类图
实例的代码
1.创建一个请求对象:TranslineQueryParam
public class TranslineQueryParam {
private Integer distance;
public Integer getDistance() {
return distance;
}
public void setDistance(Integer distance) {
this.distance = distance;
}
}
2.创建一个结果对象:TranslineResult
public class TranslineResult {
private String info;
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
}
3.创建一个抽象类:TranslineQueryHandler
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);
}
}
}
这个类中的参数nextTranslineQueryHandler用来存放下一个请求处理对象,方法deal()用于处理请求,方法doChain()用于将参数传递给下一个处理对象。
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.结果
思考
这只是责任链模式中最简单的一种代码实现,实际实现中可以根据业务要求用更灵活的方式实现