设计模式之责任链模式

 责任链模式,我的理解是将处理用户请求的过程形成链式结构,用户只关心请求处理的结果,而不关心请求是被哪个处理过程处理的。

 一个比较典型的例子是卖东西时的折扣处理,比如在卖房子的时候,客户提出的折扣请求不是都由销售人员来决定,而是根据一定的层级制定该层级的人员能够批准的折扣范围,比如,销售人员只能批准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等等。

         

posted on 2015-01-19 23:32  qingfei  阅读(146)  评论(0编辑  收藏  举报