责任链模式,我的理解是将处理用户请求的过程形成链式结构,用户只关心请求处理的结果,而不关心请求是被哪个处理过程处理的。
一个比较典型的例子是卖东西时的折扣处理,比如在卖房子的时候,客户提出的折扣请求不是都由销售人员来决定,而是根据一定的层级制定该层级的人员能够批准的折扣范围,比如,销售人员只能批准9折,如果折扣低于9折就要交给上级。最高一层就是CEO。
责任链模式的类图
责任链模式最大的特点是Handler中有一个其自身的引用,就是所谓的后继,当该Handler无法处理请求时就交给他的后继来处理。
示例代码
类PriceHandler:所有Handler类都要继承的抽象类,具有自身的引用。
/**处理折扣的抽象类 * @author admin * */ public abstract class PriceHandler { public PriceHandler successor; /** * 设置后继者 * @param successor */ public void setSuccessor(PriceHandler successor) { this.successor=successor; } /** * 批准折扣 * @param discount */ public abstract void calDiscount(float discount); }
类Sales:PriceHandler的子类,覆写了calDiscount方法,在无法批准该折扣的时候交给其后继者处理。
public class Sales extends PriceHandler { @Override public void calDiscount(float discount) { // TODO Auto-generated method stub if(discount>=0.9) { System.out.format("%s批准了折扣:%.2f%n",this.getClass(),discount); } else { successor.calDiscount(discount); } } }
其他的Manager,vicePresident,CEO类与此类似。
类PriceHandlerFactory:用来创建PriceHandler对象的工厂类
public class PriceHandlerFactory { public static PriceHandler createPriceHandler() { Sales sales=new Sales(); Manager manager=new Manager(); VicePresident vicePresident=new VicePresident(); CEO ceo=new CEO(); sales.setSuccessor(manager); manager.setSuccessor(vicePresident); vicePresident.setSuccessor(ceo); return sales; } }
类Client:请求折扣的类
public class Client { private PriceHandler priceHandler; public PriceHandler getPriceHandler() { return priceHandler; } public void setPriceHandler(PriceHandler priceHandler) { this.priceHandler = priceHandler; } public void sendRequest(float discount) { priceHandler.calDiscount(discount); } public static void main(String[] args) { Client client=new Client(); client.setPriceHandler(PriceHandlerFactory.createPriceHandler()); Random random=new Random(); for(int i=1;i<11;i++) { client.sendRequest(random.nextFloat()); } } }
由Client类中只有PriceHandler的引用,在Client发出请求时,Client与处理过程是通过PriceHandler与工厂类联系在一起的,我们并不知道Client的请求到底是被哪一个PriceHandler的子类处理的,我们只知道处理的结果,于是实现了较为松散的耦合。
在评价责任链模式时,可从以下两个方面来评价:
1.是否符合开闭原则:在要增加一个层级时,比如说销售组长的角色时,只需要新建一个销售组长的类,说明责任链模式是对扩展开放的,但也是要修改工厂类里面的初始化的。所以这方面比较难判断的,要根据项目对于耦合的要求来决定。
2.从性能来看,责任链模式需要通过多个Handler来处理请求,所以占用时间比使用单一的Handler的多,在内存使用来看,责任链模式需要为链上的每个类都实例化一个对象,但实际只使用了少部分的对象,所以其对于内存使用来说也是性能比较低的。AWT一开始用的是责任链模式,后来则改用了观察者模式,可见责任链模式还是有一定局限性的。
总的来说,责任链模式实现了模块间较为松散的耦合,但性能方面稍微比较逊色一点。但责任链模式的应用是非常广泛的,比如java的异常处理机制,js的事件模型,java web的FilterChain等等。
原文:http://www.cnblogs.com/qingfei1994/p/4235039.html