最近有个需求,是关于权限认证的,由于需要对传过来的用户信息进行多级处理,才得知该用户所拥有的权限。因此我决定采用责任链的模式来实现上述需求。
1.什么是责任链模式?
责任链(Chain of Responsibility)模式的定义:
为了避免请求发送者与多个请求处理者耦合在一起,于是将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。
在责任链的模式中,我们只需要将请求发送到责任链的头处理对象中,然后就不需要关心具体的处理细节已经请求对象的传递,责任链条会自行处理,直到从链条中获取到合适的处理结果,然后将结果返回。
2.责任链模式的优点和缺点
(1)优点
1.我们不用再关心不同对象的不同处理形式,只需要将对象传给责任链条,链条会自行找到合适的处理对象来处理。
2.降低了对象之间的耦合度,每个对象只需要关系下一个处理对象是谁就可以了。
3.增强了扩展性,需要新增处理对象,只需要添加到处理链条即可。并且还满足开闭原则。
4.每个类处理任务明确,满足责任单一原则。
(2)缺点
1.如果处理链条过长,那么可能会影响系统性能。
2.如果对一个请求没有合适的处理对象,那么该请求可能到链条最后也不能得到处理。
3.代码实现
普通的责任链模式实现
(1).首先写一个抽象的处理类
public abstract class AbstractChainHandler {
/**
* 下一个元素
*/
protected AbstractChainHandler nextAbstractChainHandler;
/**
* 校验结果
* @return
*/
public abstract Boolean checkAction(SourceOrderItemModel sourceOrderItemModel);
public void setAbstractChainHandler(AbstractChainHandler nextAbstractChainHandler) {
this.nextAbstractChainHandler = nextAbstractChainHandler;
}
protected Boolean checkNextHandler(SourceOrderItemModel sourceOrderItemModel){
//校验是否含有下一级处理器
if (Objects.nonNull(nextAbstractChainHandler)){
//调用下一级处理器
return nextAbstractChainHandler.checkNextHandler(sourceOrderItemModel);
}else {
//没有下一级处理器,直接返回false
return false;
}
}
}
(2)然后在写几个具体的处理类
/**
* 第一级处理器
*/
@Slf4j
public class FirstAbstractChainHandler extends AbstractChainHandler{
private AbstractChainHandler nextHandler;
@Override
public Boolean checkAction(SourceOrderItemModel sourceOrderItemModel) {
//TODO 进行第一步校验
System.out.println("第一步校验...");
return nextHandler.checkAction(sourceOrderItemModel);
}
public void setNextHandler(AbstractChainHandler handler){
this.nextHandler = handler;
}
}
/**
* 第二级处理器
*/
@Slf4j
public class SecondAbstractChainHandler extends AbstractChainHandler{
private AbstractChainHandler nextHandler;
@Override
public Boolean checkAction(SourceOrderItemModel sourceOrderItemModel) {
//TODO 进行第二步校验
System.out.println("第儿步校验.....");
return nextHandler.checkAction(sourceOrderItemModel);
}
public void setNextHandler(AbstractChainHandler handler){
this.nextHandler = handler;
}
}
/**
* 第三级处理器,也是最后一级
*/
@Slf4j
public class ThirdAbstractChainHandler extends AbstractChainHandler{
@Override
public Boolean checkAction(SourceOrderItemModel sourceOrderItemModel) {
//TODO 进行第三步校验
System.out.println("第三步校验.......");
return false;
}
}
//测试用例
public class test {
public static void main(String[] args) {
//创建链条节点
FirstAbstractChainHandler first = new FirstAbstractChainHandler();
SecondAbstractChainHandler second = new SecondAbstractChainHandler();
ThirdAbstractChainHandler third = new ThirdAbstractChainHandler();
//装配处理链条
first.setNextHandler(second);
second.setNextHandler(third);
first.checkAction(new SourceOrderItemModel());
}
}
以下是调用结果:
上面是普通的责任链模式,缺点很明显,整个责任链都需要自己手动搭建,代码很不雅观,而且写法很笨拙。因此我们在此基础上又融入了单例模式和工厂模式,由此来优化当前的写法。
升级版责任链模式
(1)抽象的处理者(这一步不变)
public abstract class AbstractChainHandler {
/**
* 下一个元素
*/
protected AbstractChainHandler nextAbstractChainHandler;
/**
* 校验结果
* @return
*/
public abstract Boolean checkAction(SourceOrderItemModel sourceOrderItemModel);
public void setAbstractChainHandler(AbstractChainHandler nextAbstractChainHandler) {
this.nextAbstractChainHandler = nextAbstractChainHandler;
}
protected Boolean checkNextHandler(SourceOrderItemModel sourceOrderItemModel){
//校验是否含有下一级处理器
if (Objects.nonNull(nextAbstractChainHandler)){
//调用下一级处理器
return nextAbstractChainHandler.checkNextHandler(sourceOrderItemModel);
}else {
//没有下一级处理器,直接返回false
return false;
}
}
}
(2)具体的处理者(这次链条的装配,我们不在处理者里装配,只做业务处理)
/**
* 第一级处理器
*/
@Slf4j
public class FirstAbstractChainHandler extends AbstractChainHandler{
@Override
public Boolean checkAction(SourceOrderItemModel sourceOrderItemModel) {
//TODO 进行第一步校验
System.out.println("第一步校验...");
return checkNextHandler(sourceOrderItemModel);
}
}
/**
* 第二级处理器
*/
@Slf4j
public class SecondAbstractChainHandler extends AbstractChainHandler{
@Override
public Boolean checkAction(SourceOrderItemModel sourceOrderItemModel) {
//TODO 进行第二步校验
System.out.println("第儿步校验.....");
return checkNextHandler(sourceOrderItemModel);
}
}
/**
* 第三级处理器,也是最后一级
*/
@Slf4j
public class ThirdAbstractChainHandler extends AbstractChainHandler{
@Override
public Boolean checkAction(SourceOrderItemModel sourceOrderItemModel) {
//TODO 进行第三步校验
System.out.println("第三步校验.......");
return false;
}
}
(3)处理者的单例类(为了优雅的装配链条,我们在获取处理者的单例时,再进行链条装配)
/**
* 第一级处理器单例
*/
public class FirstChainHandlerSingleton {
private volatile static FirstChainHandlerSingleton singleton;
private AbstractChainHandler abstractChainHandler;
private static final Object lock = new Object();
public AbstractChainHandler getAbstractChainHandler() {
return abstractChainHandler;
}
//在这里进行链条装配
public FirstChainHandlerSingleton() {
abstractChainHandler = new FirstAbstractChainHandler();
SecondAbstractChainHandler secondAbstractChainHandler = new SecondAbstractChainHandler();
abstractChainHandler.setAbstractChainHandler(secondAbstractChainHandler);
ThirdAbstractChainHandler thirdAbstractChainHandler = new ThirdAbstractChainHandler();
secondAbstractChainHandler.setAbstractChainHandler(thirdAbstractChainHandler);
}
public static FirstChainHandlerSingleton getSingleton(){
if (singleton == null){
synchronized (Singleton.class){
if (singleton == null){
singleton = new FirstChainHandlerSingleton();
}
}
}
return singleton;
}
}
/**
* 第二级处理器单例
*/
public class SecondChainHandlerSingleton {
private volatile static SecondChainHandlerSingleton singleton;
private AbstractChainHandler abstractChainHandler;
private static final Object lock = new Object();
public AbstractChainHandler getAbstractChainHandler() {
return abstractChainHandler;
}
//在这里进行链条装配
public SecondChainHandlerSingleton() {
abstractChainHandler = new SecondAbstractChainHandler();
ThirdAbstractChainHandler thirdAbstractChainHandler = new ThirdAbstractChainHandler();
abstractChainHandler.setAbstractChainHandler(thirdAbstractChainHandler);
}
public static SecondChainHandlerSingleton getSingleton(){
if (singleton == null){
synchronized (Singleton.class){
if (singleton == null){
singleton = new SecondChainHandlerSingleton();
}
}
}
return singleton;
}
}
/**
* 第三级处理器单例
*/
public class ThirdChainHandlerSingleton {
private volatile static ThirdChainHandlerSingleton singleton;
private AbstractChainHandler abstractChainHandler;
private static final Object lock = new Object();
public AbstractChainHandler getAbstractChainHandler() {
return abstractChainHandler;
}
//在这里进行链条装配
public ThirdChainHandlerSingleton() {
abstractChainHandler = new ThirdAbstractChainHandler();
}
public static ThirdChainHandlerSingleton getSingleton(){
if (singleton == null){
synchronized (Singleton.class){
if (singleton == null){
singleton = new ThirdChainHandlerSingleton();
}
}
}
return singleton;
}
}
(4)处理链条的工厂类(为了优雅的获取处理链条,我们直接在服务启动时,就将链条构造好,并注入到容器中,后期如果需要使用可直接获取)
@Component
@DependsOn("springContextConfig")
public class ChainHandlerFactory {
/**
* Map<单据类型, 调用链Handler>
*/
private Map<String, AbstractChainHandler> chainHandlerMap;
@PostConstruct
public void init(){
chainHandlerMap = new HashMap<>();
//第一级处理handler链路
chainHandlerMap.put(SourceOrderType.AUCTION.name(), FirstChainHandlerSingleton.getSingleton().getAbstractChainHandler());
//第二级处理handler链路
chainHandlerMap.put(SourceOrderType.BID.name(), SecondChainHandlerSingleton.getSingleton().getAbstractChainHandler());
//第三级处理handler链路
chainHandlerMap.put(SourceOrderType.ENQUIRY.name(), SecondChainHandlerSingleton.getSingleton().getAbstractChainHandler());
}
public AbstractChainHandler getHanlderByType(String type){
return chainHandlerMap.get(type);
}
}