This is the 10th day of my participation in the Gwen Challenge.More article challenges
preface
- If your current system has many classes that are only distinguished by their behavior, then using the policy pattern dynamically allows an object to choose one behavior among many, embrace the policy pattern.
- If your system needs to dynamically choose between several algorithms, embrace the policy pattern.
- If an object has a lot of behavior that, without a proper pattern, would have to be implemented using multiple conditional selection statements, embrace the strategic pattern.
Demand Background:
The upstream service will push several fixed keys to my current system, which will not change frequently. As the downstream service, we need to do a series of business operations for each key. Of course, the first thing that comes to mind is switch case or if-else. Of course, this is also possible, but as a good programmer, does this fit our style? Do not meet! One word, we have to “edge” up ah, OK! The next show operation moment (of course, not all for show, the strategic model also has the advantages of this, it is extremely suitable for solving our current business model;
Solution:
Extract the parts of a class that change frequently or may change in the future as an interface, and then include an instance of that object in the class so that instances of the class can invoke the behavior of the class that implements the interface at runtime.
In fact, our core idea is the same as if-else, according to different keys to dynamically find different business logic; Through the policy pattern, we adjust the code structure, using interface + implementation class + dispatch logic to strengthen the maintainability of the code structure.
Let’s use an example to introduce:
1, create an Enum class for the key we need to maintain to add enumeration
/** * @author taoze * @version 1.0 * @date 4/21/21 11:39am */ public enum CarEnum {BenzG500(" BenzG500 "," BenzG500 "), BMW320 (" 320 ", "BMW"), AoDi (" A4 ", "audi"), TOYOTA (" camry ", "TOYOTA"); public String version; public String brand; CarEnum(String version,String brand) { this.version = version; this.brand = brand; } public String getVersion() { return version; } public void setVersion(String version) { this.version = version; } public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } public static String getValue(String code) { for (CarEnum ele : values()) { if(ele.getBrand().equals(code)) return ele.getVersion(); } return null; }}Copy the code
Create a base class for policy assignment
/** * @author taoze * @version 1.0 * @date 6/8/21 5:27pm */ @component @slf4j public Class StrategyFactory { private Map<String, Function<String, String>> checkResultDispatcherComX = new HashMap<>(); @Autowired private StrategyService strategyService; / * * * initializes the business logic dispatch Map the deposit the value of which is lambda expressions * / @ PostConstruct public void checkResultDispatcherComXInit () { checkResultDispatcherComX.put(CarEnum.AoDi.brand, code -> strategyService.buyAoDi(code)); checkResultDispatcherComX.put(CarEnum.BenzG500.brand, code -> strategyService.buyBeanz(code)); checkResultDispatcherComX.put(CarEnum.BMW320.brand, code -> strategyService.buyBMW(code)); checkResultDispatcherComX.put(CarEnum.TOYOTA.brand, code -> strategyService.buyToyota(code)); } public String getCheckResultComX(String key) { Function<String, String> result = checkResultDispatcherComX.get(key); if(result! =null){ String apply = result.apply(key); return apply; } return null; }}Copy the code
3. Allocate policy business implementation interface
@author Taoze * @version 1.0 * @date 6/8/21 5:21pm */ public Interface StrategyService {String buyAoDi(String code); String buyBeanz(String code); String buyBMW(String code); String buyToyota(String code); }Copy the code
4. Business implementation methods
/** ** * @author Taoze * @version 1.0 * @date 6/8/21 5:22pm */ @service @slf4j public Class StrategyServiceImpl implements StrategyService { @Override public String buyAoDi(String code) { System.out.println(CarEnum.getValue(code)); return CarEnum.getValue(code); } @Override public String buyBeanz(String code) { System.out.println(CarEnum.getValue(code)); return CarEnum.getValue(code); } @Override public String buyBMW(String code) { System.out.println(CarEnum.getValue(code)); return CarEnum.getValue(code); } @Override public String buyToyota(String code) { System.out.println(CarEnum.getValue(code)); return CarEnum.getValue(code); }}Copy the code
5. Call the interface
@GetMapping("/testStrategy") public WechatServerResult testStrategy(@RequestParam("key") String key) { log.info("param = {}",key); return WechatServerResult.build(() -> strategyFactory.getCheckResultComX(key)); }Copy the code
All work ~ done ~
Conclusion:
In fact, the strategy mode is not perfect, it has its own shortcomings, we should consider its maintainability and practicality when using; When a large number of new policies are added, the policy class will expand and become more complex to maintain.
Advantages: 1. The algorithm can be switched freely. 2. Avoid using multiple conditional judgments. 3. Good expansibility.
Disadvantages: 1. Policy classes will increase. 2. All policy classes need to be exposed.
Ok! The strategy mode is shared here, we can choose whether to carry out the “show” operation according to their own situation, I hope it can be helpful to you, there are wrong places I hope we can put forward, grow together;
Neat makes for great code, and there’s only so much detail