责任链模式是一种对象的行为模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。
涉及角色:
1.抽象处理者(Handler)角色:定义出一个处理请求的接口。如果需要,接口可以定义出一个方法以设定和返回对下家的引用。这个角色通常由一个Java抽象类或者Java接口实现。
涉及角色:
1.抽象处理者(Handler)角色:定义出一个处理请求的接口。如果需要,接口可以定义出一个方法以设定和返回对下家的引用。这个角色通常由一个Java抽象类或者Java接口实现。
2.具体处理者(ConcreteHandler)角色:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。
举例例子说明一下就是:
假设存在A、B、C、D四种处理方式(具体处理者),对于一个新的请求进来,只会匹配到其中的某一种处理。按照通常的写法,会用到if...else if...eles这种分支来判断到底使用哪一种处理方式。大家都知道这种写法并不好。使用责任链模式时,可以规避这种分支的方式。通过创建一个责任链,将ABCD按顺序链接起来,如A->B->C->D这样的顺序。每次新的请求进来,都最先访问链头的处理者A,如果A受理了,就返回处理结果,如果不是A能处理的请求,就传递给B处理,依次下去。这里的ABCD顺序可以是线性的,也可以是循环的,还可以是树形结构中的一部分,具体情况具体分析。
代码示例:
假设现在要设计一套支付系统,包括微信支付,支付宝支付,工行卡支付,账号卡支付,现金支付等。需要根据不同的支付选择处理逻辑。
public abstract class PaymentTypeHandler { //保存下一个handler节点 private PaymentTypeHandler handler; public PaymentTypeHandler(){} public PaymentTypeHandler(PaymentTypeHandler handler){ this.handler = handler; } public final void pay(String type){ if (getType().equals(type)){ //符合当前方式,直接调用方法 this.handler(); }else { //如果不符合当前方式,则换用下一种方式 if (getHandler() != null){ getHandler().pay(type); }else { //不符合当前方式,也没有指定下一种方式,则使用默认方式 System.out.println("默认使用现金支付"); } } } //子类实现,用于判断是否符合该handler类型 protected abstract String getType(); //子类实现具体的处理逻辑 protected abstract void handler(); public PaymentTypeHandler getHandler() { return handler; } public void setHandler(PaymentTypeHandler handler) { this.handler = handler; } }
public class WXPay extends PaymentTypeHandler { public WXPay(){} public WXPay(PaymentTypeHandler handler){ super(handler); } protected String getType(){ return "微信"; } protected void handler() { System.out.println("使用微信支付"); } }
public class Alipay extends PaymentTypeHandler { public Alipay(){} public Alipay(PaymentTypeHandler handler){ super(handler); } protected String getType(){ return "支付宝"; } protected void handler() { System.out.println("使用支付宝支付"); } }
public class ICBC extends PaymentTypeHandler{ public ICBC(){} public ICBC(PaymentTypeHandler handler){ super(handler); } protected String getType(){ return "ICBC"; } protected void handler() { System.out.println("使用工行卡支付"); } }
public class CMB extends PaymentTypeHandler { public CMB(){} public CMB(PaymentTypeHandler handler){ super(handler); } protected String getType(){ return "CMB"; } protected void handler() { System.out.println("使用招行卡支付"); } }测试方法:
public static void main(String[] args) { //创建责任链节点 PaymentTypeHandler handler1 = new Alipay(); PaymentTypeHandler handler2 = new WXPay(); PaymentTypeHandler handler3 = new ICBC(); PaymentTypeHandler handler4 = new CMB(); //组装责任链 handler1.setHandler(handler2); handler2.setHandler(handler3); handler3.setHandler(handler4); //每次都从链头开始执行 handler1.pay("ICBC"); handler1.pay("微信"); handler1.pay("预付卡"); }
执行结果:
使用工行卡支付
使用微信支付
默认使用现金支付
本例中,在抽象处理类中增加了默认支付方式,当所有的具体处理类都不能处理的时候,使用抽象处理类里的处理方法。