目录
一.定义
使多个对象都有机会处理请求,解耦请求发送者和请求接收者,将请求接收者连成一条链,并沿着这条链传递请求,直到有对象处理该请求为止。
从定义的描述看责任链模式有两个核心概念,一是降低请求发送者和处理者耦合性,请求者不需要关心处理者的实现细节;二是多个处理者构成一条处理链,由链去处理相似的请求,并在链中决定由谁来处理这个请求。
二.类图
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缺点
同样,责任链模式也有两个缺点,一是性能问题,每次处理都需要遍历整个链,如果链太长效率较低;二是调试困难,责任链的调试类似于递归,需要不断的遍历、匹配处理者,如遇链太长逻辑较复杂。
上述的两个问题在链较短的情况下都不存在,因而在使用责任链时,一定要控制好链的长度。