不少状况下,一个软件系统中能够处理某个请求的对象不知一个,好比采购单的审批,主任,副董事长,董事长,董事会均可以处理采购单,他们能够构成一条处理采购单的链式结构,采购单沿着这条链进行传递,这条链就叫职责链。java
职责链能够是一条直线,一个环或者一个树形结构,最多见的职责链是直线型,即沿着一条单向的链来传递请求。链上的每个对象都是请求处理者,职责链模式能够将请求的处理者组织成一条链,并让请求沿着链传递,由链上的处理者对请求进行处理,客户端无须关系请求的处理细节以及具体的传递,只须要将请求发送到链上便可,实现请求发送者以及请求处理者的解耦。编程
职责链模式:避免将请求发送者与接收者耦合在一块儿,让多个对象都有机会接收请求,将这些对象链接成一条链,而且沿着这条链传递请求,直到有对象处理它为止。微信
职责链模式是一种行为型模式。dom
Handler
(抽象处理者):定义一个处理请求的接口,通常为抽象类。由于每个处理者的下家仍是一个处理者,所以在抽象处理者中定义了一个抽象处理者的对象做为对下一个处理者的引用,经过该引用,处理者能够连成一条链ConcreteHandler
(具体处理者):抽象处理者的子类,实现具体处理方法,在处理前须要判断是否具备处理权限,若是拥有权限则处理,没有则转发到下一个处理者protected
abstract class Handler { protected Handler successor; public void setSuccessor(Handler successor) { this.successor = successor; } public abstract void handleRequest(int num); }
拥有一个设置下一处理者的对象,能够经过setter注入,同时声明抽象处理方法。ide
class ConcreteHandler1 extends Handler { @Override public void handleRequest(int num) { if(num < 10) { System.out.println("处理小于10的数字:"+num); } else successor.handleRequest(num); } } class ConcreteHandler2 extends Handler { @Override public void handleRequest(int num) { if(num < 20) { System.out.println("处理大于等于10且小于20的数字:"+num); } else successor.handleRequest(num); } } class ConcreteHandler3 extends Handler { @Override public void handleRequest(int num) { if(num < 30) { System.out.println("处理大于等于20且小于30的数字:"+num); } else successor.handleRequest(num); } }
继承抽象处理者,首先判断是否拥有权限处理(这里是一个简单的if判断),若是有就处理,没有的话经过protected
对象,也就是转发给下一个处理者处理。性能
public static void main(String[] args) { Handler handler = new ConcreteHandler1(); Handler handler2 = new ConcreteHandler2(); Handler handler3 = new ConcreteHandler3(); handler.setSuccessor(handler2); handler2.setSuccessor(handler3); handler.handleRequest(3); handler.handleRequest(15); handler.handleRequest(22); }
客户端针对抽象处理者编程,须要建立每个具体处理者对象,而且自定义职责链:测试
handler.setSuccessor(handler2); handler2.setSuccessor(handler3);
接着调用对应的处理者处理便可。this
设计一个采购单审批系统,分级进行,根据金额不一样由不一样层次的人员审批,主任能够审批5w如下的采购单,副董事长能够审批5w-10w,董事长能够审批10w-50w,50w以上须要由董事会审批,使用职责链模式设计该系统。
设计以下:spa
Approver
Director
+VicePresident
+President
+Congress
PurchaseRequest
代码以下:设计
//抽象处理者 abstract class Approver { protected Approver successor; public void setSuccessor(Approver successor) { this.successor = successor; } public abstract void processRequest(PurchaseRequest request); } //具体处理者:主任 class Director extends Approver { @Override public void processRequest(PurchaseRequest request) { if(request.getAmount() < 50000) System.out.println("主任审批一笔\n金额为"+request.getAmount()+"\nid为"+request.getId()+"\n的采购单\n"); else successor.processRequest(request); } } //具体处理者:副董事长 class VicePresident extends Approver { @Override public void processRequest(PurchaseRequest request) { if(request.getAmount() < 100000) System.out.println("副董事长审批一笔\n金额为"+request.getAmount()+"\nid为"+request.getId()+"\n的采购单\n"); else successor.processRequest(request); } } //具体处理者:董事长 class President extends Approver { @Override public void processRequest(PurchaseRequest request) { if(request.getAmount() < 500000) System.out.println("董事长审批一笔\n金额为"+request.getAmount()+"\nid为"+request.getId()+"\n的采购单\n"); else successor.processRequest(request); } } //具体处理者:董事会 class Congress extends Approver { @Override public void processRequest(PurchaseRequest request) { System.out.println("董事会审批一笔\n金额为"+request.getAmount()+"\nid为"+request.getId()+"\n的采购单\n"); } } //请求类:采购单 class PurchaseRequest { private double amount; private String id; private static final String STR = "xcnvj232cvm"; private static final Random random = new Random(); public PurchaseRequest(double amount) { this.amount = amount; //简易的随机字符串 this.id = STR.substring(0,random.nextInt(STR.length()-1)+1).repeat(random.nextInt(3)+2); } public double getAmount() { return this.amount; } public void setAmount(double amount) { this.amount = amount; } public String getId() { return this.id; } public void setId(String id) { this.id = id; } }
测试:
public static void main(String[] args) { Approver director = new Director(); Approver vicePresident = new VicePresident(); Approver president = new President(); Approver congress = new Congress(); director.setSuccessor(vicePresident); vicePresident.setSuccessor(president); president.setSuccessor(congress); director.processRequest(new PurchaseRequest(12345)); director.processRequest(new PurchaseRequest(54321)); director.processRequest(new PurchaseRequest(123456)); director.processRequest(new PurchaseRequest(654321)); }
输出以下:
职责链模式能够分为纯的职责链模式与不纯的职责链模式。
一个纯的职责链模式要求一个具体处理者对象只能在两个行为中选择一个,要么承担所有责任,要么将责任推给下家,不容许出现某一个具体处理者对象在承担了一部分或所有责任后又将责任向下传递的状况。
并且在纯的职责链模式中,要求一个请求必须被某一个处理者对象接收,不能出现某个请求未被任何一个处理者对象处理的状况,好比前面的采购单例子。
在一个不纯的职责链模式中,容许某个请求被一个具体处理者部分处理后再向下传递,或者一个具体处理者处理完某请求后其猴戏处理者能够继续处理该请求,并且一个请求能够最终不被任何处理者对象所接收。
在Java AWT 1.0中的事件处理模型应用就是不纯的职责链模式,基本原理以下:因为窗口组件通常位于容器组件中,当事件发生在窗口组件上时,先经过组件对象的handleEvent()
方法传递给相应的事件处理方法,该事件处理方法将处理该事件,而后决定是否将该事件向上一级容器组件传播,上级容器组件在接到事件以后能够继续处理此事件并决定是否继续向上级容器组件传播,直到顶层容器组件为止。若是一直都没有处理方法则不处理该事件。
这种事件处理机制又叫事件浮升机制,JDK1.1后使用观察者模式来代理职责链模式处理事件。
若是以为文章好看,欢迎点赞。
同时欢迎关注微信公众号:氷泠之路。