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

来源:互联网 发布:c语言编程代码 编辑:程序博客网 时间:2024/06/06 12:31

定义:

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


在这里举一个用户注册的例子,这个例子源于《设计模式之禅》上关于本模式的讲解,说是作者在实际项目中用到的这个责任链模式,我这里进行了简化操作,该例子描述如下:用户分为两类,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);}@Overridepublic 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);}@Overridepublic 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()方法中判断是否已经超过阀值。