责任链模式是将链中的每个节点看作是一个对象,每个节点处理的请求各不相同,且内部自动维护下一节点对象。
当一个请求从链的首端发起时,会沿着链的路径依次传递给每一个节点对象,直至有一个对象处理这个请求为止。
责任链模式主要是解耦了请求和处理,客户只需将请求发送到链上即可,无需关注请求的内容和处理细节。
以登录为例,正常我们登录会验证用户名密码、验证码、用户是否为黑名单、获取用户对应的权限菜单等。我们可以将这一系列过程抽象成几部分。
@Data
@AllArgsConstructor
public class User {
	private String username;
	
	private String password;
	
	private String captcha;
}
public abstract class AbstractHandler<T> {
	
	protected AbstractHandler chain;
	
	public void next(AbstractHandler handler) {
		this.chain = handler;
	}
	
	public abstract void doHandler(User user);
	
	public static class Builder<T> {
		
		private AbstractHandler<T> head;
		
		private AbstractHandler<T> tail;
		
		public Builder<T> addHandler(AbstractHandler<T> handler) {
			if (this.head == null) {
				this.head = this.tail = handler;
				return this;
			}
			this.tail.next(handler);
			this.tail = handler;
			return this;
		}
		
		public AbstractHandler<T> builder() {
			return this.head;
		}
	}
}
public class ValidatePassword extends AbstractHandler {
	/**
	 * 密码,就当是从数据库查询出来的
	 */
	private static final String PASSWORD = "123456";
	
	
	@Override
	public void doHandler(User user) {
		if (user == null || StringUtils.isBlank(user.getUsername()) || StringUtils.isBlank(user.getPassword())) {
			System.out.println("用户名和密码不能为空");
			return;
		}
		if (!PASSWORD.equals(user.getPassword())) {
			System.out.println("密码错误");
			return;
		}
		System.out.println("用户名密码验证通过");
		chain.doHandler(user);
	}
}
public class ValidateCaptcha extends AbstractHandler {
	
	private static final String CAPTCHA = "qwer";
	@Override
	public void doHandler(User user) {
		if (StringUtils.isBlank(user.getCaptcha()) || !CAPTCHA.equals(user.getCaptcha())) {
			System.out.println("验证码错误");
			return;
		}
		System.out.println("验证码验证通过");
		chain.doHandler(user);
	}
}
public class ValidateBlackUser extends AbstractHandler {
	
	private static final String BLACK_USER = "xiaowang";
	
	@Override
	public void doHandler(User user) {
		if (BLACK_USER.equals(user.getUsername())) {
			System.out.println("黑名单校验未通过");
			return;
		}
		System.out.println("黑名单验证通过");
		chain.doHandler(user);
	}
}
public class MenuService extends AbstractHandler {
	
	private static final List<String> MENU_LIST = Arrays.asList("用户菜单","角色菜单","部门菜单");
	
	@Override
	public void doHandler(User user) {
		System.out.println("根据用户" +user.getUsername()+ "获取菜单->" + MENU_LIST);	
	}
}
public class RequestHandler {
	
	private static AbstractHandler abstractHandler;
	
	static {
		AbstractHandler.Builder builder = new AbstractHandler.Builder();
		builder.addHandler(new ValidatePassword())
				.addHandler(new ValidateCaptcha())
				.addHandler(new ValidateBlackUser())
				.addHandler(new MenuService());
		abstractHandler = builder.builder();
	}
	
	public static void doRequest(User user) {
		abstractHandler.doHandler(user);
	}
}
public class TestResponsibility {
	public static void main(String[] args) {
		User user = new User("lisi", "123456", "qwer");
		RequestHandler.doRequest(user);
	}
}
/*
 用户名密码验证通过
 验证码验证通过
 黑名单验证通过
 根据用户lisi获取菜单->[用户菜单, 角色菜单, 部门菜单] 
*/
最常见的就是Filter过滤器,将所有实现了Filter接口的类放到一个List,按顺序进行调用。
原文:https://www.cnblogs.com/ns-study/p/14626714.html