Java设计模式学习 - 责任链模式

1,560 阅读2分钟

个人博客项目地址

希望各位帮忙点个star,给我加个小星星✨


设计模式-责任链


简单介绍

责任链模式(Chain of Responsibility):使多个对象都有机会处理同一个请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。


举个🌰

一节课堂,有课前、课中和课后,不同老师、不同地点或者不同时间,课堂的内容和实际都有所不同,如果在一个service中写业务逻辑,代码可读性会比较差,别人维护也麻烦,所以使用责任链模式,将每一步分开维护,大概流程如下:

  • 编写课程前、中、后的执行逻辑和回滚逻辑
  • 一个业务结束后,调用下一个业务的执行逻辑
  • 一个业务失败后,调用上一个业务的回滚逻辑

PS:左边的课程和规则是一个整体,责任链真正处理的流程是右边的逻辑。


实现代码

这个例子还用到了工厂方法和单例方法,以及与Spring整合了,各位看官在实际使用中,要根据自身情况,适当的修改。

抽象RuleHandler

/**
 * @author JingQ at 2018/9/7
 */
public abstract class AbstractRuleHandler {

    /**
     *  上一个处理器
     */
    private AbstractRuleHandler preHandler;

    /**
     *  下一个处理器
     */
    private AbstractRuleHandler nextHandler;

    /**
     * 责任链模式
     * @param experiment    experiment
     */
    public void doHandler(Experiment experiment, ClassRule rule) {
        try {
            doHandleReal(experiment, rule);
        } catch (Exception e) {
            rollBack(experiment, rule);
            return;
        }
        if (nextHandler != null) {
            nextHandler.doHandler(experiment, rule);
        }
    }

    /**
     * 回滚策略
     * @param experiment    experiment
     * @param rule          rule
     */
    public void rollBack(Experiment experiment ,ClassRule rule) {
        rollBackReal(experiment, rule);
        if (preHandler != null) {
            preHandler.rollBack(experiment, rule);
        }
    }

    /**
     * 真正处理的逻辑
     * @param experiment  experiment
     * @param rule          规则
     */
    public abstract void doHandleReal(Experiment experiment, ClassRule rule);

    /**
     * 回滚逻辑
     * @param experiment    experiment
     * @param rule          规则
     */
    public abstract void rollBackReal(Experiment experiment, ClassRule rule);

    public AbstractRuleHandler setPreHandler(AbstractRuleHandler preHandler) {
        this.preHandler = preHandler;
        return preHandler;
    }

    public AbstractRuleHandler setNextHandler(AbstractRuleHandler nextHandler) {
        this.nextHandler = nextHandler;
        nextHandler.setPreHandler(this);
        return nextHandler;
    }
}

第一个Handler

@Service
public class ClassBeginRuleHandler extends AbstractRuleHandler {

    @Override
    public void doHandleReal(Experiment experiment, ClassRule rule) {
        experiment.setName(rule.getRule1());
        System.out.println("success rule1 : " + rule.getRule1());
    }

    @Override
    public void rollBackReal(Experiment experiment, ClassRule rule) {
        System.out.println("error rule1 : " + rule.getRule1());
    }
}

由于第二个与第一个处理一样,就不贴出来了


第三个Handler

@Service
public class ClassEndRuleHandler extends AbstractRuleHandler {

    @Autowired
    private ClassroomService classroomService;

    @Override
    public void doHandleReal(Experiment experiment, ClassRule rule) {
        Classroom classroom = classroomService.getById(experiment.getClassroomId());
        if (classroom != null) {
            if (StringUtils.equals(classroom.getClassroom(), rule.getRule3())) {
                experiment.setClassroomId(classroom.getId());
            }
            System.out.println(classroom.getClassroom() + "-" + rule.getRule3());
        } else {
            System.out.println("classroom is null , success rule 3 :"  + rule.getRule3());
        }
    }

    @Override
    public void rollBackReal(Experiment experiment, ClassRule rule) {
        System.out.println("error Rule 3 : " + rule.getRule3());
    }
}

工厂整合类

/**
 * 工厂方法
 * @author JingQ at 2018/9/7
 */
@Service
public class AbstractRuleFactory {

    @Autowired
    private ClassEndRuleHandler classEndRuleHandler;

    @Autowired
    private ClassingRuleHandler classingRuleHandler;

    @Autowired
    private ClassBeginRuleHandler classBeginRuleHandler;

    private AbstractRuleHandler ruleHandler;

    private AbstractRuleFactory() {
    }

    // 使用了单例模式
    public AbstractRuleHandler getInstance() {
        if (ruleHandler == null) {
            synchronized (AbstractRuleFactory.class) {
                if (ruleHandler == null) {
                    ruleHandler = classBeginRuleHandler;
                    ruleHandler.setNextHandler(classingRuleHandler).setNextHandler(classEndRuleHandler);
                }
            }
        }
        return ruleHandler;
    }
}

执行效果

可以看到,通过factory.getInstance().doHandle(experiment, rule),责任链会根据设定的顺序进行执行,每个业务操作都进行分开了,代码也更加整洁,维护性也更强了。


参考资料

  1. Java设计模式----责任链模式
  2. Java设计模式应用——责任链模式