Java/Android 设计模式系列(15)--责任链模式
2017-08-27 16:14
411 查看
这篇博客我们来介绍一下责任链模式(Chain-of-responsibility Pattern),责任联模式又称为职责链模式,是行为型设计模式之一。顾名思义,责任链模式中存在一个链式结构,多个节点首尾相连,每个节点都可以被拆开再连接,因此,链式结构具有很好的灵活性。将这样一种结构应用于编程领域,将每一个节点看作是一个对象,每一个对象拥有不同的处理逻辑,将一个请求从链式的首段发出,沿着链的路径依次传递给每一个节点对象,直至有对象处理这个请求为止,这就是责任链或者职责链的通俗定义。
责任链模式的使用场景:
多个对象可以处理统一请求,但具体由哪个对象处理则在运行时动态决定;
在请求处理者不明确的情况下向多个对象中的一个提交一个请求;
需要动态指定一组对象处理请求。
责任链模式有两大角色:
Handler:抽象处理者角色,声明一个请求处理的方法,并在其中保持对下一个处理节点 Hanlder 对象的引用;
ConcreteHandler:
对于请求 Request 来说,在大多数情况下,责任链中的请求和对应的处理规则是不尽相同的,在这种情况下可以将请求进行封装,同时对请求的处理规则也进行封装作为一个独立的对象,如上图所示。据此可以写出通用代码,首先是 Handler 角色:
AbstractHandler.class
ConcreteHandler1.class
ConcreteHandler2.class
然后是请求角色:
AbstractRequest.class
ConcreteRequest1.class
ConcreteRequest2.class
最后客户端测试代码:
结果如下:
ViewGroup 和 View 中 touch 事件的分发,子 View 的 onTouchEvent 返回 true 代码消费该事件并不再传递,false 代表不消费并且传递到父 ViewGroup 去处理,这些树形结构的子 View 就是责任链上一个个处理对象;
OrderedBroadcast,广播的每一个接收者按照优先级依次接受消息,如果处理完成之后可以调用 abortBroadcast 终止广播,不是自己处理的就可以传递给下一个处理者;
try-catch语句,每一个 catch 根据 Exception 类型进行匹配,形成一个责任链,如果有一个 catch 语句与该 Exception 符合,这个 Exception 就交由给它进行处理,之后所有 catch 语句都不会再次执行。
我们这就以 wiki 上的代码为例:每个人都有一个支出审批的额度,超过审批额度之后将会传递给下一个审批人,直到最后:
审批人相关类
审批类
最后是客户端的测试代码:
代码简洁明了,都应该能看懂。
很多资料中会介绍纯和不纯的责任链模式,在标准的责任链模式中,责任链上的一个节点只允许有两个行为:处理或者推给下个节点处理,而不允许处理完之后又推给下个节点,前者被很多资料称为纯的责任链模式,而后者被称为不纯的责任链模式。其实在实际的系统里,纯的责任链很难找到。如果坚持责任链不纯便不是责任链模式,那么责任链模式便不会有太大意义了。
http://blog.csdn.net/jason0539/article/details/45091639
设计模式总目录
Java/Android 设计模式系列–目录特点
使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系,将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。责任链模式的使用场景:
多个对象可以处理统一请求,但具体由哪个对象处理则在运行时动态决定;
在请求处理者不明确的情况下向多个对象中的一个提交一个请求;
需要动态指定一组对象处理请求。
UML类图
责任链模式的 uml 图如下所示:责任链模式有两大角色:
Handler:抽象处理者角色,声明一个请求处理的方法,并在其中保持对下一个处理节点 Hanlder 对象的引用;
ConcreteHandler:
对于请求 Request 来说,在大多数情况下,责任链中的请求和对应的处理规则是不尽相同的,在这种情况下可以将请求进行封装,同时对请求的处理规则也进行封装作为一个独立的对象,如上图所示。据此可以写出通用代码,首先是 Handler 角色:
AbstractHandler.class
public abstract class AbstractHandler { protected AbstractHandler nextHandler; public final void handleRequest(AbstractRequest request) { if (getHandlerLevel() == request.getLevel()) { handle(request); } else { if (nextHandler != null) { nextHandler.handleRequest(request); } else { System.out.print("there is no handler that can handle this request"); } } } protected abstract int getHandlerLevel(); protected abstract void handle(AbstractRequest request); }
ConcreteHandler1.class
public class ConcreteHandler1 extends AbstractHandler{ @Override protected int getHandlerLevel() { return 1; } @Override protected void handle(AbstractRequest request) { System.out.print("ConcreteHandler1 handle this request : " + request.getContent() + "\n"); } }
ConcreteHandler2.class
public class ConcreteHandler2 extends AbstractHandler{ @Override protected int getHandlerLevel() { return 2; } @Override protected void handle(AbstractRequest request) { System.out.print("ConcreteHandler2 handle this request : " + request.getContent() + "\n"); } }
然后是请求角色:
AbstractRequest.class
public abstract class AbstractRequest { private Object object; public AbstractRequest(Object object) { this.object = object; } public Object getContent() { return object; } public abstract int getLevel(); }
ConcreteRequest1.class
public class ConcreteRequest1 extends AbstractRequest{ public ConcreteRequest1(Object object) { super(object); } @Override public int getLevel() { return 1; } }
ConcreteRequest2.class
public class ConcreteRequest2 extends AbstractRequest{ public ConcreteRequest2(Object object) { super(object); } @Override public int getLevel() { return 2; } }
最后客户端测试代码:
public class Client { public static void main(String[] args) { AbstractHandler handler1 = new ConcreteHandler1(); AbstractHandler handler2 = new ConcreteHandler2(); handler1.nextHandler = handler2; AbstractRequest request1 = new ConcreteRequest1("request1"); AbstractRequest request2 = new ConcreteRequest2("request2"); handler1.handleRequest(request1); handler1.handleRequest(request2); } }
结果如下:
示例与源码
其实责任链模式在实际项目过程中遇到的非常多,Android 和 Java 源码也一样,举几个简单的例子:ViewGroup 和 View 中 touch 事件的分发,子 View 的 onTouchEvent 返回 true 代码消费该事件并不再传递,false 代表不消费并且传递到父 ViewGroup 去处理,这些树形结构的子 View 就是责任链上一个个处理对象;
OrderedBroadcast,广播的每一个接收者按照优先级依次接受消息,如果处理完成之后可以调用 abortBroadcast 终止广播,不是自己处理的就可以传递给下一个处理者;
try-catch语句,每一个 catch 根据 Exception 类型进行匹配,形成一个责任链,如果有一个 catch 语句与该 Exception 符合,这个 Exception 就交由给它进行处理,之后所有 catch 语句都不会再次执行。
我们这就以 wiki 上的代码为例:每个人都有一个支出审批的额度,超过审批额度之后将会传递给下一个审批人,直到最后:
审批人相关类
public abstract class PurchasePower { protected static final double BASE = 500; protected PurchasePower successor; abstract protected double getAllowable(); abstract protected String getRole(); public void setSuccessor(PurchasePower successor) { this.successor = successor; } public void processRequest(PurchaseRequest request){ if (request.getAmount() < this.getAllowable()) { System.out.println(this.getRole() + " will approve $" + request.getAmount()); } else if (successor != null) { successor.processRequest(request); } } }
public class ManagerPPower extends PurchasePower { protected int getAllowable(){ return BASE*10; } protected String getRole(){ return "Manager"; } } public class DirectorPPower extends PurchasePower { protected int getAllowable(){ return BASE*20; } protected String getRole(){ return "Director"; } } public class VicePresidentPPower extends PurchasePower { protected int getAllowable(){ return BASE*40; } protected String getRole(){ return "Vice President"; } } public class PresidentPPower extends PurchasePower { protected int getAllowable(){ return BASE*60; } protected String getRole(){ return "President"; } }
审批类
public class PurchaseRequest { private double amount; private String purpose; public PurchaseRequest(double amount, String purpose) { this.amount = amount; this.purpose = purpose; } public double getAmount() { return amount; } public void setAmount(double amt) { amount = amt; } public String getPurpose() { return purpose; } public void setPurpose(String reason) { purpose = reason; } }
最后是客户端的测试代码:
public class CheckAuthority { public static void main(String[] args) { ManagerPPower manager = new ManagerPPower(); DirectorPPower director = new DirectorPPower(); VicePresidentPPower vp = new VicePresidentPPower(); PresidentPPower president = new PresidentPPower(); manager.setSuccessor(director); director.setSuccessor(vp); vp.setSuccessor(president); // Press Ctrl+C to end. 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()); manager.processRequest(new PurchaseRequest(d, "General")); } } catch(Exception e) { System.exit(1); } } }
代码简洁明了,都应该能看懂。
总结
责任链模式的优点显而易见,可以对请求者和处理者关系解耦,提高代码的灵活性,通过改变链内的成员或调动他们的次序,允许你动态地新增或者删除职责;但是责任链模式最大的缺点在于对链中请求处理者的遍历,如果处理者太多那么必定会影响性能,特别是在一些递归调用中,而且不容易观察运行时的特征,有碍于除错。很多资料中会介绍纯和不纯的责任链模式,在标准的责任链模式中,责任链上的一个节点只允许有两个行为:处理或者推给下个节点处理,而不允许处理完之后又推给下个节点,前者被很多资料称为纯的责任链模式,而后者被称为不纯的责任链模式。其实在实际的系统里,纯的责任链很难找到。如果坚持责任链不纯便不是责任链模式,那么责任链模式便不会有太大意义了。
源码下载
https://github.com/Jakey-jp/Design-Patterns/tree/master/ChainOfResponsibilityPattern引用
https://en.wikipedia.org/wiki/Chain-of-responsibility_patternhttp://blog.csdn.net/jason0539/article/details/45091639
相关文章推荐
- java/android 设计模式学习笔记(15)---责任链模式
- Java/Android 设计模式系列(1)--单例模式
- Java/Android 设计模式系列(6)--适配器模式
- Java/Android 设计模式系列(23)--解释器模式
- Java/Android 设计模式系列(13)--享元模式
- Java/Android 设计模式系列(2)--观察者模式
- Java/Android 设计模式系列(18)--中介者模式
- Java/Android 设计模式系列(14)--外观模式
- Java/Android 设计模式系列(16)--命令模式
- Java/Android 设计模式系列(22)--模板方法模式
- Android设计模式系列--原型模式
- 极速理解设计模式系列:12.责任链模式(Chain of Responsibility Pattern)
- Android设计模式系列--原型模式
- Android设计模式系列
- Android设计模式系列(2)--SDK源码之观察者模式
- Android设计模式系列(6)--SDK源码之享元模式
- Android设计模式系列
- Android设计模式之责任链模式
- Android设计模式系列-适配器模式
- Android设计模式系列(12)--SDK源码之生成器模式(建造者模式)