首页 > 技术文章 > 【设计模式】责任链模式

dream-to-pku 2018-08-24 10:19 原文

一、责任链模式的优点

责任链模式非常显著的优点是将请求和处理分开。请求者可以不用知道是谁处理的,处理者可以不用知道请求的全貌,两者解耦,提供系统的灵活性。

二、责任链模式的缺点

责任链有两个非常显著的缺点:一是性能问题,每个请求都是从链头遍历到链尾,特别是在链比较长的时候,性能是一个非常大的问题,。二是调试很不方便,特别是链条比较长,环节比较多的时候,由于采用了类似递归的方式,调试的时候逻辑可能比较复杂。

三、责任链模式的注意事项

链中节点数量需要控制,避免出现超长链的情况,一般的作做法是在Handler中设置一个最大节点数量,在setNext方法中判断是否已经是超过其阀值,超过则不允许该链建立,避免无意识地破坏系统性能。

四、最佳实践

在通用源码中Handler是抽象类,融合了模板方法模式,每个实现类只要实现两个方法,echo方法处理请求和getHandlerLevel获得处理级别,想想单一职责和迪米特法则,通过融合模板方式,各个实现类只要关注自己业务逻辑就成了,至于说什么事要自己处理,就让父类去决定,也就是说父类实现了请求传递的功能,子类实现请求的处理,符合单一职责原则,各个实现类只完成一个动作或逻辑,也就是只有一个原因引起类的改变。

责任链屏蔽了请求的处理过程,你发起一个请求到底是谁处理的,这个你不需要关系,只要你把请求抛给责任链的第一个处理者,最终都会返回一个结果,作为请求者可以不用知道到底是谁来处理的,这是责任链的核心。

五、代码示例

未使用责任链模式之前

package com.slp.responsibility;

public interface IHandler {

	public void HandlerMessage(IWomen women);
}
package com.slp.responsibility;

public interface IWomen {
   /**
    * 获得个人情况
    * @return
    */
	public int getType();
	
	/**
	 * 获得个人请示,要做什么?出去逛街?约会?还是看电影?
	 * @return
	 */
	public String getRequest();
}

  

package com.slp.responsibility;

public class Father implements IHandler {

	/**
	 * 未出嫁的女儿请示父亲
	 */
	@Override
	public void HandlerMessage(IWomen women) {
		System.out.println("女儿的请求是:"+women.getRequest());
		System.out.println("父亲的答复是:同意");

	}

}

  

package com.slp.responsibility;

public class Husband implements IHandler {

	@Override
	public void HandlerMessage(IWomen women) {
		System.out.println("妻子的请求是:"+women.getRequest());
		System.out.println("丈夫的答复是:同意");

	}

}

  

package com.slp.responsibility;

public class Son implements IHandler {

	@Override
	public void HandlerMessage(IWomen women) {
		System.out.println("母亲的请求是:"+women.getRequest());
		System.out.println("儿子的答复是:同意");

	}

}

  

package com.slp.responsibility;

public class Women implements IWomen {

	/**
	 * 通过int类型的参数来描述个人状况
	 */
	private int type = 0;
	/**
	 * 获取函数传过来的请求
	 */
	private String request = "";
	@Override
	public int getType() {
		return this.type;
	}

	@Override
	public String getRequest() {
		return this.request;
	}

	public Women(int type, String request) {
		super();
		this.type = type;
		this.request = request;
	}

}

  

package com.slp.responsibility;

import java.util.ArrayList;
import java.util.Random;

public class Client {

	public static void main(String[] args) {

		Random random = new Random();
		ArrayList<IWomen> arrayList = new ArrayList();
		for(int i=0;i<5;i++){
			arrayList.add(new Women(random.nextInt(4),"我要出去逛街"));
		}
		IHandler father = new Father();
		IHandler husband = new Husband();
		IHandler son = new Son();
		for (IWomen women : arrayList) {
			if(women.getType()==1){
				System.out.println("女儿向父亲请示");
				father.HandlerMessage(women);
			}else if(women.getType()==2){
				System.out.println("妻子向丈夫请示");
				husband.HandlerMessage(women);
			}else if(women.getType()==3){
				System.out.println("母亲向儿子请示");
				son.HandlerMessage(women);
			}else{
				System.out.println("不做处理");
			}
		}
	}

}  

 

使用责任链模式之后

package com.slp.responsibility.renew;

public interface IWomen {
   /**
    * 获得个人情况
    * @return
    */
	public int getType();
	
	/**
	 * 获得个人请示,要做什么?出去逛街?约会?还是看电影?
	 * @return
	 */
	public String getRequest();
}

  

package com.slp.responsibility.renew;

public abstract class Handler {

	public final static int FATHER_LEVEL_REQUEST = 1;
	public final static int HUSBAND_LEVEL_REQUEST = 2;
	public final static int SON_LEVEL_REQUEST = 1;
	//能处理的级别
	private int level = 0;
	//责任传递,下一个责任人是谁
	private Handler nextHandler;
	//每个类都有说明一下自己能处理哪些请求
	public Handler(int level) {
		this.level = level;
	}
	//一个女性要求逛街,要按这个请求处理
	public final void HandleMessage(IWomen women){
		if(women.getType() == this.level){
			this.response(women);
		}else{
			//有后续环节,才把请求往后递送
			if(this.nextHandler!=null){
				this.nextHandler.response(women);
			}else{
				System.out.println("---已经没有后续处理人了,按不同意处理---");
			}
		}
	}
	
	
	protected abstract void response(IWomen women);
	
	public void setNext(Handler handler){
		this.nextHandler = handler;
	}
}

  

package com.slp.responsibility.renew;


public class Father extends Handler{

	public Father() {
		super(Handler.FATHER_LEVEL_REQUEST);
		
	}

	@Override
	protected void response(IWomen women) {
		System.out.println("-----女儿向父亲请示----");
		System.out.println(women.getRequest());
		System.out.println("父亲的答复是:同意\n");
		
	}

}

  

package com.slp.responsibility.renew;

public class Husband extends Handler {

	public Husband() {
		super(Handler.HUSBAND_LEVEL_REQUEST);
		
	}

	@Override
	protected void response(IWomen women) {
		System.out.println("----妻子向丈夫请示----");
		System.out.println(women.getRequest());
		System.out.println("丈夫的答复是:同意\n");

	}

}

  

package com.slp.responsibility.renew;

public class Son extends Handler {

	public Son() {
		super(Handler.SON_LEVEL_REQUEST);
	}

	@Override
	protected void response(IWomen women) {
		System.out.println("------母亲向儿子请示------");
        System.out.println(women.getRequest());
        System.out.println("儿子的答复是:同意\n");
	}

}

 

package com.slp.responsibility.renew;

public class Women implements IWomen {

	private int type = 0;
	private String request ="";
	
	public Women(int type, String request) {
		super();
		this.type = type;
		switch (this.type){
		case 1:
			this.request="女儿的请求是:"+request;
			break;
		case 2:
			this.request="妻子的请求是:"+request;
			break;
		case 3:
			this.request="母亲的请求是:"+request;
			break;			
		}
	}

	@Override
	public int getType() {
		return this.type;
	}

	@Override
	public String getRequest() {
		// TODO Auto-generated method stub
		return this.request;
	}

}

  

package com.slp.responsibility.renew;

import java.util.ArrayList;
import java.util.Random;

public class Client {

	public static void main(String[] args) {

		Random random = new Random();
		ArrayList<IWomen> arrayList = new ArrayList();
		for(int i=0;i<5;i++){
			arrayList.add(new Women(random.nextInt(4),"我要出去逛街"));
		}
		Handler father = new Father();
		Handler husband = new Husband();
		Handler son = new Son();
		father.setNext(husband);
		husband.setNext(son);
		for(IWomen women :arrayList){
			father.HandleMessage(women);
		}
		
	} 

}

  

 

 

 

推荐阅读