类图待补充
- 抽象处理者(BuyPower)角色:定义个处理请求的接口。此角色由java的抽象类和java接口实现。
- 具体处理者角色(PresidentBuyPower):具体处理这街道请求之后,可以选择将请求处理掉,也可以将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理这可以访问下家。
1.定义处理请求的抽象类,handler
- 定义一个处理请求的接口
- 实现后继链(可选)
package desigh.commands.chainOfResponsibility; /** * @author lipeng24@meituan.com * @create 2017-11-06 下午12:11 **/ abstract class BuyPower { protected static final double BASE = 500;
//持有后继的责任对象 protected BuyPower successor; //设置后继的责任对象 public void setSuccessor(BuyPower buyPower) { this.successor = buyPower; } //实际处理请求的方法 abstract public void process(BuyRequest request); }
2.定义具体的处理请求类
- 处理它所负责的请求
- 可访问它的后继者
- 如果可处理该请求,就处理之,否则将该请求转发给它的后继者。
使用场景:申请经费,团建。
申请团建经费的大致流程一般是:申请人先填写申请单,然后交给领导审批,如果申请批准下来的话,领导通知申请人审批通过还是未通过。
不同的级别的领导,对于审批的额度不一样,比如经理只能审批5000以内的申请,主管只能申请10000以内的申请......
也就是说某个人提出经费申请之后,该请求会经过经理,主管,副董事长,董事长的的某一位领导来进行相应的处理,但是提出申请的人并不知道最终由谁来处理他的请求,一般申请人最终是把自己的申请提交给经理,或者最终由主管来处理他的请求。也就是当某人申请团建的经费的请求时候,请求会经过"经理->主管->副董事长->董事长"这样一个领导处理链上进行传递,发出请求的人并不知道谁会来处理他的请求,每个领导根据自己的职责范围,来判断处理请求还是把请求交给更高级别的领导,只有领导处理了,传递就结束了。
package desigh.commands.chainOfResponsibility; /**
* 董事长审批申请,可以申请经费的上限为40 * 500 * @author lipeng24@meituan.com * @create 2017-11-06 下午12:17 **/ public class PresidentBuyPower extends BuyPower { public final double ALLOWABLE = 40 * BASE; @Override public void process(BuyRequest request) { if (request.getAmount() < ALLOWABLE) { System.out.println("President will aprove $" + request.getAmount()); } else if (successor != null) { successor.process(request); } } }
package desigh.commands.chainOfResponsibility; /**
副董事长能申请的金额为30 * 500
* @author lipeng24@meituan.com * @create 2017-11-06 下午12:17 **/ public class VicePresidentBuyPower extends BuyPower { public final double ALLOWABLE = 30 * BASE; @Override public void process(BuyRequest request) { if (request.getAmount() < ALLOWABLE) { System.out.println("VicePresident will aprove $" + request.getAmount()); } else if (successor != null) { successor.process(request); } } }
package desigh.commands.chainOfResponsibility; /**
主管能够申请的金额上线为20 * 500
* @author lipeng24@meituan.com * @create 2017-11-06 下午12:17 **/ public class DirectorBuyPower extends BuyPower { public final double ALLOWABLE = 20 * BASE; @Override public void process(BuyRequest request) { if (request.getAmount() < ALLOWABLE) { System.out.println("director will aprove $" + request.getAmount()); } else if (successor != null) { successor.process(request); } } }
package desigh.commands.chainOfResponsibility;
/**
经理能够审批的金额上线为 10 * 500
* @author lipeng24@meituan.com * @create 2017-11-06 下午12:14 **/ public class ManagerBuyPower extends BuyPower { private final double ALLOWABLE = 10 * BASE; @Override public void process(BuyRequest request) { if (request.getAmount() < ALLOWABLE) { System.out.println(" Manager will approve $" + request.getAmount()); } else if (successor != null) { successor.process(request); } } }
package desigh.commands.chainOfResponsibility; /** * @author lipeng24@meituan.com * @create 2017-11-06 下午12:13 **/ public class BuyRequest { private double amount; private String purpose; public BuyRequest(double amount, String purpose) { this.amount = amount; this.purpose = purpose; } public double getAmount() { return amount; } public void setAmount(double amount) { this.amount = amount; } public String getPurpose() { return purpose; } public void setPurpose(String purpose) { this.purpose = purpose; } }
3.责任链客户端:
package desigh.commands.chainOfResponsibility; import java.io.BufferedReader; import java.io.InputStreamReader; /** * 责任链设计模式 * * @author lipeng24@meituan.com * @create 2017-11-06 下午12:08 **/ public class ChainOfResponsibilityTest { public static void main(String[] args) {
ManagerBuyPower managerBuyPower = new ManagerBuyPower(); DirectorBuyPower directorBuyPower = new DirectorBuyPower(); VicePresidentBuyPower vicePresidentBuyPower = new VicePresidentBuyPower(); PresidentBuyPower presidentBuyPower = new PresidentBuyPower(); managerBuyPower.setSuccessor(directorBuyPower); directorBuyPower.setSuccessor(vicePresidentBuyPower); vicePresidentBuyPower.setSuccessor(presidentBuyPower); try { while (true) { System.out.println("Enter the amount to check who should approve your expenditure."); System.out.print(">"); double d = Double.parseDouble(new BufferedReader(new InputStreamReader(System.in)).readLine()); managerBuyPower.process(new BuyRequest(d, "General")); } } catch (Exception exc) { System.exit(1); } } }
- 责任链的优点:将请求和处理分开。请求者可以不用知道是谁处理的,处理这者可以不用知道请求的全貌,两者解耦,提高系统的灵活性。
- 责任链的缺点:一是性能问题,每个请求都是从链头部遍历到链尾部,特别是在链比较长的时候,性能是一个非常大的问题。二是调试不方便,采用了类似递归的方式,调试不方便。
参考:
1.https://foolchild.cn/2016/07/26/chain_of_responsibility
2.https://en.wikipedia.org/wiki/Chain-of-responsibility_pattern
3.logic执行框架(责任链+模板方法) -> 组合模式 + 责任链 + 模板方法
4.https://www.cnblogs.com/java-my-life/archive/2012/05/28/2516865.html --责任链
5.基于责任链的活动模板引擎 : http://tech.lede.com/2017/02/13/rd/server/ChainOfResponsibilityForActivity/
6.基于责任链模式实现的烂机器:https://juejin.im/post/5bcd157b6fb9a05d0b146ef7?utm_source=gold_browser_extension