Personal blog project address

Hope everybody helps point a star, add a small star to me ✨


Design patterns – Chains of responsibility


A simple introduction

Chain of Responsibility: Avoid coupling between the sender and receiver of the request by giving multiple objects the opportunity to process the same request. Connect the objects into a chain and pass the request along the chain until an object processes it.


An 🌰

A class, before class, class and after class, teachers, different place or different time, the content of the classroom and actual is different, if written in a service business logic and code readability is poor, others maintenance and trouble, so using the chain of responsibility pattern, separate each step maintenance, probably process is as follows:

  • Write execution logic and rollback logic before, during, and after the lesson
  • When one business ends, the execution logic of the next business is invoked
  • When a business fails, the rollback logic of the previous business is invoked

PS: The courses and rules on the left are a whole, while the real process of the chain of responsibility is the logic on the right.


The implementation code

This example also uses the factory method and singleton method, as well as the integration with Spring, you see the officer in the actual use, according to their own situation, appropriate modification.

Abstract RuleHandler

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

    /** * Previous processor */
    private AbstractRuleHandler preHandler;

    /** * next processor */
    private AbstractRuleHandler nextHandler;

    /** * Responsibility chain mode *@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); }}/** * Rollback policy *@param experiment    experiment
     * @param rule          rule
     */
    public void rollBack(Experiment experiment ,ClassRule rule) {
        rollBackReal(experiment, rule);
        if(preHandler ! =null) { preHandler.rollBack(experiment, rule); }}/** * the actual processing logic *@param experiment  experiment
     * @paramRule rule * /
    public abstract void doHandleReal(Experiment experiment, ClassRule rule);

    /** * rollback logic *@param experiment    experiment
     * @paramRule 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);
        returnnextHandler; }}Copy the code

The first 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()); }}Copy the code

Since the second and the first treatment is the same, I will not post it


The third 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()); }}Copy the code

Factory integration

/** * factory method *@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(a) {}// Use singleton mode
    public AbstractRuleHandler getInstance(a) {
        if (ruleHandler == null) {
            synchronized (AbstractRuleFactory.class) {
                if (ruleHandler == null) { ruleHandler = classBeginRuleHandler; ruleHandler.setNextHandler(classingRuleHandler).setNextHandler(classEndRuleHandler); }}}returnruleHandler; }}Copy the code

perform

As you can see, with factory.getInstance().dohandle (experiment, rule), the chain of responsibility is executed in the order set, each business operation is separated, and the code is cleaner and more maintainable.


The resources

  1. Java design pattern —- Chain of Responsibility pattern
  2. Java Design Pattern application – Chain of Responsibility pattern