责任链模式是将链中的每一个节点看作是一个对象,每个节点处理的请求都不相同,且内部自动维护下一个节点对象。每个请求从链式首端发出,沿着链依次经过每个节点,如果当前节点无法处理自动传递给下一个节点,直到链上某个节点处理完请求,则链结束。属于行为型模式。
适用场景:
责任链在框架中的应用:
JDK中Filter, Spring对FilterChain进行了实现,通过List将所有Filter封装起来
Netty中ChannelPipeline, pipeline由ChannelHandler组成,pipeline中有head和tail组成一个双向链,ChannelHandler分为InBoundHandler(数据输入进行解码)和OutBoundHandler(对数据进行编码输出)。
优点:
缺点:
下面写个简单的模拟用户登录的代码来演示下责任链模式的使用
public class LoginService {
public void login(String username, String pwd) {
if (StringUtils.isEmpty(username) || StringUtils.isEmpty(pwd)) {
System.out.println("用户名或密码为空!");
return;
}
User user = checkExist(username, pwd);
if (null == user) {
System.out.println("用户不存在!");
return;
}
System.out.println("登陆成功");
if (!"admin".equals(user.getRole())) {
System.out.println("您不是管理员,没有操作权限!");
return;
}
System.out.println("操作成功");
}
private User checkExist(String username, String pwd) {
Map userMap = new HashMap<>();
userMap.put("Lucifer&&&admin", new User("Lucifer", "admin", "admin"));
if (userMap.containsKey(username + "&&&" + pwd)) {
return userMap.get(username + "&&&" + pwd);
}
return null;
}
}
public class LoginTest {
public static void main(String[] args) {
LoginService service = new LoginService();
service.login("Lucifer", "admin");
}
}
链上节点抽象类
public abstract class AbstractHandler {
protected AbstractHandler nextHandler;
protected void next(AbstractHandler handler) {
this.nextHandler = handler;
}
public abstract void doHandler(User obj);
public static class Builder {
private AbstractHandler head;
private AbstractHandler tail;
public Builder addHandler(AbstractHandler handler) {
if (this.head == null) {
this.head = this.tail = handler;
return this;
}
this.tail.next(handler);
this.tail = handler;
return this;
}
public AbstractHandler build() {
return this.head;
};
}
}
链上的三个节点处理类
public class ValidationHandler extends AbstractHandler {
@Override
public void doHandler(User user) {
if (StringUtils.isEmpty(user.getUsername()) || StringUtils.isEmpty(user.getPwd())) {
System.out.println("用户名或密码为空!");
return;
}
this.nextHandler.doHandler(user);
}
}
public class DBHandler extends AbstractHandler {
@Override
public void doHandler(User u) {
User user = checkExist(u.getUsername(), u.getPwd());
if (null == user) {
System.out.println("用户不存在!");
return;
}
System.out.println("登陆成功");
this.nextHandler.doHandler(user);
}
private User checkExist(String username, String pwd) {
Map userMap = new HashMap<>();
userMap.put("Lucifer&&&admin", new User("Lucifer", "admin", "admin"));
if (userMap.containsKey(username + "&&&" + pwd)) {
return userMap.get(username + "&&&" + pwd);
}
return null;
}
}
public class AuthHandler extends AbstractHandler {
@Override
public void doHandler(User user) {
if (!"admin".equals(user.getRole())) {
System.out.println("您不是管理员,没有操作权限!");
return;
}
System.out.println("操作成功");
}
}
将所有节点的处理类串成一个链,并从链首执行
public class LoginService {
public void login(String username, String pwd) {
AbstractHandler.Builder builder = new AbstractHandler.Builder();
builder.addHandler(new ValidationHandler()).addHandler(new DBHandler()).addHandler(new AuthHandler());
User u = new User();
u.setUsername(username);
u.setPwd(pwd);
builder.build().doHandler(u);
}
}
public class LoginTest {
public static void main(String[] args) {
LoginService service = new LoginService();
service.login("Lucifer", "admin");
}
}
责任链模式的实现原理?
责任链模式有两种实现方式,单向链表,双向链表,通过上下文保存头和尾,每个handler中设置下一个节点,但是链不能太长,否则影响性能,还要避免节点之间互相引用出现死循环