定义:

使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系,将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。


在这里举一个用户注册的例子,这个例子源于《设计模式之禅》上关于本模式的讲解,说是作者在实际项目中用到的这个责任链模式,我这里进行了简化操作,该例子描述如下:用户分为两类,VIP用户户和普通用户,VIP用户是在他们公司办理过业务的用户,注册时只要提供VIP序列号和其他一些必要信息就可以了,激活是通过发送邮件激活的,而普通用户注册,则需要填写电话号码,并且激活账号是通过发送手机短信来激活的。

在这里处理两种注册的类就成了责任链,用户的注册信息从责任链一端传入,若是自己的处理级别则处理,否则往责任链的下一级传送,直到该注册信息被处理。这里责任链只是由两个类构成的,比较简单,其类图如下:


设计模式学习笔记——责任链模式_电话

实现代码如下:

public abstract class User {
	
	public static final int VIP=1;//VIP用户
	public static final int COMMON=2;//普通用户
	
	private int type;//用户的类型
	private String name;//用户名
	private String password;//密码
	
	public User(int type, String name, String password) {
		this.type = type;
		this.name = name;
		this.password = password;
	}
	
	public int getType() {
		return type;
	}
	public void setType(int type) {
		this.type = type;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
}
/*
 * VIP用户是在公司已经有过业务的,注册时只需要提供VIP序列号就可以了
 */
public class VIPUser extends User {
	
	private String VIPNum;//VIP序列号
	
	public VIPUser(int type, String name, String password) {
		super(type, name, password);
	}
	
	public String getVIPNum() {
		return VIPNum;
	}

	public void setVIPNum(String vIPNum) {
		VIPNum = vIPNum;
	}
	
	public String toString(){
		return this.getName()+" "+this.getPassword()+" "+this.getType()+" "+this.getVIPNum();
	}
}
/*
 * 普通用户,没有在公司办理过业务,则需要提供电话号码
 */
public class CommonUser extends User {

	private String mobileNum;//电话号码

	public CommonUser(int type, String name, String password) {
		super(type, name, password);
	}
	
	public String getMobileNum() {
		return mobileNum;
	}

	public void setMobileNum(String mobileNum) {
		this.mobileNum = mobileNum;
	}
	
	public String toString(){
		return this.getName()+" "+this.getPassword()+" "+this.getType()+" "+this.getMobileNum();
	}
}
public abstract class Handler {
	public final static int VIP_LEVEL_REQUEST=1;
	public final static int COMMON_LEVEL_REQUEST=2;
	
	private int level=0;//能处理的级别
	private Handler nextHandler;//责任链传递,下一个责任链是谁
	
	public Handler(int level,Handler nextHandler){
		this.level=level;
		this.nextHandler=nextHandler;
	}
	
	//设置下一个处理类
	public void setNext(Handler handler){
		this.nextHandler=handler;
	}
	
	//注册,由子类去多态的实现
	public abstract void register(User user);
	
        //此处也体现了模板方法模式
	public final void HandleRequest(User user){
		if(user.getType()==this.level){//如果用户类型本类能处理的级别,在在本类中进行处理
			this.register(user);
		}
		else{//否则在下一个负责人不为空的情况下,移交给下一个负责人处理
			if(this.nextHandler!=null){
				this.nextHandler.HandleRequest(user);
			}
			else{
				System.out.println("can not handle");
			}
		}
	}
}
public class CommonHandler extends Handler {

	public CommonHandler(int level, Handler nextHandler) {
		super(level, nextHandler);
	}

	@Override
	public void register(User user) {
		CommonUser commonUser=(CommonUser)user;
		System.out.println("您的注册信息为:"+commonUser.toString());
		System.out.println("已向您的手机:"+commonUser.getMobileNum()+"发送激活码...\n");
	}
}
public class VIPHandler extends Handler {

	public VIPHandler(int level, Handler nextHandler) {
		super(level, nextHandler);
	}

	@Override
	public void register(User user) {
		VIPUser vipUser=(VIPUser)user;
		System.out.println("您的注册信息为:"+vipUser.toString());
		System.out.println("已向您的邮箱中发送了一封确认邮件,请注意查收...\n");
	}
}
public class Client {
	public static void main(String[] args) {
		
		VIPUser vipUser=new VIPUser(User.VIP,"suo","123456h");
		vipUser.setVIPNum("88888888");
		
		CommonUser commonUser=new CommonUser(User.COMMON,"piao","654321h");
		commonUser.setMobileNum("15200852293");
		
		Handler commonHandler=new CommonHandler(Handler.COMMON_LEVEL_REQUEST,null);
		Handler vipHandler=new VIPHandler(Handler.VIP_LEVEL_REQUEST,null);
		
		commonHandler.setNext(vipHandler);//指定下一个处理类
		
		commonHandler.HandleRequest(vipUser);
		commonHandler.HandleRequest(commonUser);
	}
}



责任链模式的优点:

将请求和处理分开,特别是当请求和处理相对较复杂的时候,将两者解耦,提高系统的灵活性。责任链模式屏蔽了请求的处理过程,你发起一个请求到底是谁处理的,这个不用关心,只要把请求抛给责任链的第一个处理者,最终会返回一个结果。


责任链模式的缺点:

缺点很明显,即当责任链过长,则会影响性能,所以一般的做法是在Handler中设置一个最大的结点数量,在setNext()方法中判断是否已经超过阀值。