Practice of spring boot custom initialization Bean+HashMap optimization strategy mode

Keywords: Java Spring Spring Boot

Policy pattern: it defines algorithm families and encapsulates them separately so that they can be replaced with each other. This pattern makes the changes of the algorithm independent of the customers using the algorithm.

The traditional policy mode is generally to create a public interface, define a public method, then create an entity class to implement the public interface, rewrite the public method according to their respective logic, create a context object whose behavior changes with the change of the policy object, and call different interface implementation class methods according to different parameters, Different results can be obtained only by changing parameters.

However, it can also be clearly found that the implementation method of * * policy mode has a large amount of code, and it also needs to customize the parameters to be transmitted. A certain number of if/else may be introduced, * * has a certain optimization space. Next, I will share an optimization method of policy mode in combination with my actual development experience to further optimize the code structure and reduce the amount of code.

First, it is necessary to create a public interface and define a public method, then create an entity class to implement the public interface and rewrite the public method according to their respective logic. The reference code is as follows:

Define the public interface CommonService and the public method push()

1 package com.itcq.service.StrategyPattern;
2 
3 public interface CommonService {
4     String push(String key);
5 }

Create three different interface implementation classes and override the push() method

package com.itcq.service.StrategyPattern;
import org.springframework.stereotype.Service;

@Service
public class TestOne implements CommonService {
    @Override
    public String push(String key) {
        return "1.This is the pattern:" + key;
    }
}
package com.itcq.service.StrategyPattern;

import org.springframework.stereotype.Service;

@Service
public class TestTwo implements CommonService{
    @Override
    public String push(String key) {
        return "2.This is the pattern:"+key;
    }
}
package com.itcq.service.StrategyPattern;
import org.springframework.stereotype.Service;

@Service
public class TestThree implements CommonService{
    @Override
    public String push(String key) {
        return "3.This is the pattern:"+key;
    }
}

The next step is the focus. We use springboot to initialize beans and HashMap to optimize the policy pattern

@Service
public class TestServiceTwo implements InitializingBean {

    @Autowired
    private ApplicationContext applicationContext;

    private HashMap<String, CommonService> hashmap = new HashMap<>();

    @Override
    public void afterPropertiesSet() {

        hashmap.put(StrategyTestEnum.STRATEGY_ONE.getTitle(), new TestOne());
        hashmap.put(StrategyTestEnum.STRATEGY_TWO.getTitle(), this.applicationContext.getBean(TestTwo.class));
        hashmap.put(StrategyTestEnum.STRATEGY_THREE.getTitle(), this.applicationContext.getBean(TestThree.class));
    }
}
@Getter
public enum StrategyTestEnum {
    STRATEGY_ONE("one", "Mode I"),
    STRATEGY_TWO("two", "Mode II"),
    STRATEGY_THREE("three", "Mode III"),
    ;

    private String title;
    private String value;

    StrategyTestEnum(String title, String value) {
        this.title = title;
        this.value = value;
    }
}

TestServiceTwo implements the InitializingBean interface. The InitializingBean interface provides a way for beans to initialize methods. It only includes the afterpropertieset method. All classes that inherit this interface will execute this method when initializing beans.

A hashmap set is defined to store different public interface implementation class objects. Here, the parameters are extracted into an enumeration class, and the Bean object is obtained by using the SpringBoot advanced container ApplicationContext. Of course, it is also possible to directly new an implementation class object here. Different parameters and implementation objects are encapsulated in the map set to realize one-to-one correspondence between parameters and logic.

The test method is as follows: obtain the corresponding implementation class object through the key of hashmap, so there is no need to customize the parameter type, completely eliminate if/else, and do not expose too much business logic to method callers.

1 public String testMethod2(String key) {
2 
3         CommonService commonService = hashmap.get(key);
4         Assert.notNull(commonService, "Parameter error,Pattern not found");
5         return commonService.push(key);
6     }

Finally, call the method at the controller layer to test:

@Autowired
    private TestServiceTwo testServiceTwo;

    @GetMapping("/test/two")
    public String testMethodTwo(@RequestParam(name = "key") String key) {

        return testServiceTwo.testMethod2(key);
    }

The test results are as follows:

When the parameters are correct:

In case of parameter error:


This custom initialization bean+hashmap method is used to optimize the policy mode, optimize the code structure, and completely eliminate if/else. I think it can improve the code quality.

Posted by leoo24 on Sat, 18 Sep 2021 06:27:20 -0700