Strategy mode + factory mode business instance in SpringBoot (interface parameter transfer-enumeration class query strategy mapping relationship-execute different strategies) to avoid a large number of if-else

Scenes

Design pattern - example of strategy pattern usage in Java:

Design Patterns - Examples of Strategy Patterns Used in Java

The above is an example of the use of the strategy pattern in Java.

Let's look at an example of actual use in SpringBoot.

Business scene:

There are multiple coal mines, and signal lights have multiple manufacturers/rules, and each coal mine corresponds to a signal light.

It is necessary to write a general interface, obtain the corresponding signal light rules of the coal mine according to the different request codes passed, and execute the corresponding signal light rules to obtain data.

Note:

Blog:
Overbearing rogue temperament blog_CSDN Blog-C#, Architecture Road, Blogger in SpringBoot

accomplish

1. Create a new signal light rule interface class

public interface SignalLightRules {

    List<SignalrightDevsDTO> getSignalrightDevsDtoList(String mineApiCode);

}

The method getSignalrightDevsDtoList is used to obtain signal light information.

2. Create the implementation class of manufacturer 1/rule 1

@Component(Constants.SIFANGJI)
public class SiFangJiSignalLightRules implements SignalLightRules{

    @Autowired
    private SNDataUploadServiceImpl snDataUploadService;

    @Autowired
    private BusSignallightControlService busSignallightControlService;

    @Override
    public List<SignalrightDevsDTO> getSignalrightDevsDtoList(String mineApiCode) {
        //获取所有信号灯id
        List<Long> signalLightIdList = busSignallightControlService.selectBusSignallightControlIdList();
        List<SignalrightDevsDTO> signalrightDevsDtoList = snDataUploadService.getSignalrightDevsDtoList(signalLightIdList,mineApiCode);
        return signalrightDevsDtoList;
    }
}

Pay attention to adding annotations here

@Component(Constants.SIFANGJI)

And the name uses a constant of the constant class.

Attached constant class

public class Constants {

    public static final String SIFANGJI = "sifangji";

    public static final String KEERMA = "keerma";

}

Then the two services called in the specific method of obtaining signal light data are related to the specific business of the manufacturer/rules.

3. Create the implementation class of manufacturer 2/rule 2

@Component(Constants.KEERMA)
public class KeErMaSignalLightRules implements SignalLightRules{
    @Override
    public List<SignalrightDevsDTO> getSignalrightDevsDtoList(String mineApiCode) {
        return new ArrayList<>();
    }
}

Here, the specific business implementation directly returns an empty list.

4. Create a new semaphore factory class to obtain the corresponding semaphore rules

@Component
public class SignalLightRulesFactory {

    //Spring会自动将Strategy接口的实现类注入到这个Map中,key为bean id 即前面@Component注解指定的名称,value值则为对应的策略实现类
    @Autowired
    Map<String,SignalLightRules> signalLightRulesStrategy;

    private static final SignalLightRules DEFAULT_RULES = new SiFangJiSignalLightRules();

    public  SignalLightRules getSignalLightRules(String signalLightKey){
        SignalLightRules signalLightRules = signalLightRulesStrategy.get(signalLightKey);
        return signalLightRules == null?DEFAULT_RULES:signalLightRules;
    }
}

Note that the @Component annotation is added here, and @Autowired is added to the map that stores the rules,

Spring will automatically inject the implementation class of the Strategy interface into this Map, and the key is the bean id, which is the name specified in the previous @Component annotation.

The value value is the corresponding policy implementation class.

5. Different coal mines may use the same or different signal light rules, so it is necessary to configure a storage for the mapping relationship between coal mines and signal light rules.

import com.badao.demo.constant.Constants;
import org.springframework.lang.Nullable;
import java.util.HashMap;
import java.util.Map;

public enum MineMessageEnum
{
    JJT("jjt", "0001","名称1", Constants.SIFANGJI),
    ZLW("zlw", "0002","名称2",Constants.SIFANGJI),
    CCL("ccl", "0003","名称3",Constants.KEERMA);

    private final String apiCode;
    private final String mineCode;
    private final String mineName;
    private final String signalRule;

    private static final Map<String, MineMessageEnum> mappings = new HashMap<>();

    static
    {
        for (MineMessageEnum messageEnum : values())
        {
            mappings.put(messageEnum.apiCode, messageEnum);
        }
    }

    @Nullable
    public static MineMessageEnum resolve(@Nullable String mineApiCode)
    {
        return (mineApiCode != null ? mappings.get(mineApiCode) : null);
    }

    MineMessageEnum(String apiCode, String mineCode, String mineName,String signalRule)
    {
        this.apiCode = apiCode;
        this.mineCode = mineCode;
        this.mineName = mineName;
        this.signalRule = signalRule;
    }

    public String getApiCode() {
        return apiCode;
    }

    public String getMineCode() {
        return mineCode;
    }

    public String getMineName() {
        return mineName;
    }

    public String getSignalRule() {
        return signalRule;
    }
}

Here, an enumeration class is used to store the corresponding relationship between apiCode and signalRule.

Then initialize in the static static code block, store all the mapping relationships in the map, and provide a method to obtain the value according to the key.

6. In the actual business Controller layer

    @GetMapping("/signalright_devs")
    public AjaxResult SignalRightDevs(@RequestParam("mineApiCode") String mineApiCode)
    {
        try{
            MineMessageEnum resolve = MineMessageEnum.resolve(mineApiCode);
            if(null == resolve){
                return AjaxResult.error(HttpStatus.BAD_REQUEST, Constants.NO_API_CODE);
            }else {
                SignalLightRules signalLightRules = signalLightRulesFactory.getSignalLightRules(resolve.getSignalRule());
                List<SignalrightDevsDTO> signalrightDevsDTOS = signalLightRules.getSignalrightDevsDtoList(mineApiCode);
                if(null != signalrightDevsDTOS && signalrightDevsDTOS.size()>0){
                    return AjaxResult.success(signalrightDevsDTOS);
                }else {
                    return AjaxResult.success();
                }
            }
        }catch (Exception exception){
            System.out.println("SignalRightDevs:"+exception.getMessage());
            return AjaxResult.error(HttpStatus.ERROR,Constants.SERVER_ERROR);
        }
    }

First, the interface passes the apiCode parameter, and judges whether it is a legal parameter, and returns a custom error message if it does not exist.

If it exists, get the corresponding semaphore rule, through

signalLightRulesFactory.getSignalLightRules(resolve.getSignalRule());

Get the specific rules, pay attention to injecting the semaphore factory above.

    @Autowired
    private SignalLightRulesFactory signalLightRulesFactory;

7. Test

Pass the apicode corresponding to rule 1 and return the corresponding business rule data

 

Pass the apicode corresponding to rule 2 and return empty data

 

passing illegal parameters

 

Guess you like

Origin blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/130503707