定义:
使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系,将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。
在这里举一个用户注册的例子,这个例子源于《设计模式之禅》上关于本模式的讲解,说是作者在实际项目中用到的这个责任链模式,我这里进行了简化操作,该例子描述如下:用户分为两类,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()方法中判断是否已经超过阀值。