责任链模式

目录

 

一.定义

二.类图

三.实战案例

3.1用户注册类图

3.2代码

四.总结

4.1优点

4.2缺点


一.定义

使多个对象都有机会处理请求,解耦请求发送者和请求接收者,将请求接收者连成一条链,并沿着这条链传递请求,直到有对象处理该请求为止。

从定义的描述看责任链模式有两个核心概念,一是降低请求发送者和处理者耦合性,请求者不需要关心处理者的实现细节;二是多个处理者构成一条处理链,由链去处理相似的请求,并在链中决定由谁来处理这个请求。

二.类图

Request:请求对象。

Handler:父类处理器。

ConcreteHandler:子处理器。

责任链模式

三.实战案例

本文以用户注册为例子,使用责任链模式编写注册流程。我们假设系统支持普通用户、VIP两种注册方式。

普通用户需要提供用户名、手机号。

VIP用户需提供用户名、邮箱、序列号。

3.1用户注册类图

仿照责任链模式类图,用户注册流程相关类图如下:

RegisterRequest:用户注册请求对象

Handler:处理注册请求基类

CommonHandler:普通用户注册处理器

VIPHandler:VIP用户注册处理器

责任链模式

3.2代码

package cn.lzz.responsibility;

public class RegisterRequest {

    //用户名
    private String userName;

    //手机号
    private String phoneNum;

    //序列号
    private String serialNum;

    //邮箱
    private String eMail;

    //注册类型,1:普通用户,2:VIP用户
    private String registerType;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPhoneNum() {
        return phoneNum;
    }

    public void setPhoneNum(String phoneNum) {
        this.phoneNum = phoneNum;
    }

    public String getSerialNum() {
        return serialNum;
    }

    public void setSerialNum(String serialNum) {
        this.serialNum = serialNum;
    }

    public String geteMail() {
        return eMail;
    }

    public void seteMail(String eMail) {
        this.eMail = eMail;
    }

    public String getRegisterType() {
        return registerType;
    }

    public void setRegisterType(String registerType) {
        this.registerType = registerType;
    }
}
package cn.lzz.responsibility;

/**
 * 基类处理器
 */
public abstract class Handler {

    private Handler nextHandler;

    public Handler(){

    }

    public Handler(Handler next){
        this.nextHandler=next;
    }

    /**
     * 处理请求
     * @param register
     */
    public void handlerRequest(RegisterRequest register) {
        //可以处理
        if(this.support(register)){
            this.handler(register);
        }else{
            if(null!=this.nextHandler){
                this.nextHandler.handlerRequest(register);
            }else {
                throw new RuntimeException("无法处理");
            }
        }
    }

    protected abstract boolean support(RegisterRequest register);


    protected abstract void handler(RegisterRequest register);

    public Handler getNextHandler() {
        return nextHandler;
    }

    public void setNextHandler(Handler nextHandler) {
        this.nextHandler = nextHandler;
    }
}
package cn.lzz.responsibility;

/**
 * 普通用户处理器
 */
public class CommonHandler extends Handler {

    @Override
    protected boolean support(RegisterRequest register) {
        if(null!=register &&"1".equals(register.getRegisterType())){
            return true;
        }
        return false;
    }

    @Override
    protected void handler(RegisterRequest register) {
        System.out.println("模拟普通用户注册流程。。。。。");
    }
}
package cn.lzz.responsibility;

/**
 * VIP 用户注册处理器
 */
public class VIPHandler extends Handler {

    @Override
    protected boolean support(RegisterRequest register) {
        if(null!=register &&"2".equals(register.getRegisterType())){
            return true;
        }
        return false;
    }

    @Override
    protected void handler(RegisterRequest register) {
        System.out.println("模拟VIP注册用户流程。。。。");
    }
}
package cn.lzz.responsibility;

public class RegisterClient {
    public static void main(String[] args) {
        Handler common=new CommonHandler();
        Handler vip=new VIPHandler();
        //拦截器链的第一个处理器是普通用户
        common.setNextHandler(vip);

        //VIP用户注册
        RegisterRequest vipReq=new RegisterRequest();
        vipReq.setRegisterType("2");
        vipReq.seteMail("xxxx@xxx.com");
        common.handlerRequest(vipReq);

        //普通用户注册
        RegisterRequest commonReq=new RegisterRequest();
        commonReq.setRegisterType("1");
        commonReq.seteMail("yyyy@yyyy.com");
        common.handlerRequest(commonReq);

        //异常用户注册
        RegisterRequest exeReq=new RegisterRequest();
        exeReq.setRegisterType("3");
        exeReq.seteMail("yyyy@yyyy.com");
        common.handlerRequest(exeReq);


    }
}
模拟VIP注册用户流程。。。。
模拟普通用户注册流程。。。。。
Exception in thread "main" java.lang.RuntimeException: 无法处理
	at cn.lzz.responsibility.Handler.handlerRequest(Handler.java:30)
	at cn.lzz.responsibility.Handler.handlerRequest(Handler.java:28)
	at cn.lzz.responsibility.RegisterClient.main(RegisterClient.java:26)

四.总结

4.1优点

责任链模式有两个优点,一是解耦请求和处理,请求方不需要知道处理者具体的实现细节;二是便于扩展,只需在链上添加一个处理器就可以多一种处理方式,不用修改原有代码,符合开闭原则。

4.2缺点

同样,责任链模式也有两个缺点,一是性能问题,每次处理都需要遍历整个链,如果链太长效率较低;二是调试困难,责任链的调试类似于递归,需要不断的遍历、匹配处理者,如遇链太长逻辑较复杂。

上述的两个问题在链较短的情况下都不存在,因而在使用责任链时,一定要控制好链的长度。

 

 

上一篇:在abap中(Clear,Free, Refesh)的用法


下一篇:[TFS] TFS 2010 建立 Team 项目集合与 Team 项目 (TFS 2010 Create Team Project Collection And Team Project)