Click for PDF manual V2.0 – > interview | springboot | springcloud | programming ideas

This article describes how to use the policy pattern and how the Map+ functional interface solves the if-else problem “better”.

demand

Recently a service was written to query the issuing type grantType and claim rule based on the type resourceType and encoding resourceId of the coupon

Implementation method:

  1. Determines which table to query based on the coupon type resourceType ->
  2. Query coupon distribution method grantType and claim rule in the corresponding data table according to the code resourceId ->

There are several types of coupons that correspond to different database tables:

  • Red envelope — A list of rules for giving red envelopes
  • Shopping coupon — A list of shopping coupons
  • QQ member
  • Take-away member

The actual coupon is much more than that, and the requirement is that we write a business dispatch logic

The first idea that comes to mind is if-else or switch case:

Switch (resourceType){case "resourceType ": Query the distribution mode of the resourceType break; Case "coupon ": Query the coupon distribution mode break; Elseif "QQ member ": break; Case "Takeaway member" : break; . Default: logger.info(" This coupon type resourceType and corresponding distribution method cannot be found "); break; }Copy the code

If you do this, the code for a method is too long, affecting readability. (There is only one sentence in the above case, but there are actually many lines)

And because the entire if-else code has many lines, it is not easy to modify, and the maintainability is low.

The strategy pattern

The strategy mode is to extract the logic in the if statement to write a class. If you want to modify a logic, only modify the logic of a specific implementation class, maintainability will be much better.

The strategy pattern

“Policy pattern is still if-else for business logic dispatch”, just a little more maintainable than if-else in the first way…

Switch (resourceType){case "resourceType ": String grantType=new Context(new RedPaper()).contextInterface (); break; Case "Shopping coupon ": String grantType=new Context(new Shopping()).contextInterface (); break; . Default: logger.info(" This coupon type resourceType and corresponding distribution method cannot be found "); break;Copy the code

But the disadvantages are also obvious:

  • If there are many if-else judgments, there will also be many corresponding specific strategy implementation classes. The above specific strategy implementation classes are only two. The way to query the distribution of red envelopes is written in the class RedPaper, and the Shopping vouchers are written in another class Shopping. That resource type many QQ member and takeout member, do not have to write two more classes? A little bit of trouble
  • “Unable to overlook the business logic of the dispatch”

Map+ Functional interface

Lambda expressions, a new feature of Java8, are used

  • The judgment criteria are placed in the key
  • The corresponding business logic is placed in the value

The advantage of writing this way is very intuitive, you can directly see ** “determine the business logic corresponding to the condition” **

Requirement: Query distribution method “grantType” ** according to coupon (resource) type ** “resourceType” and code “resourceId”

The code:

@Service public class QueryGrantTypeService { @Autowired private GrantTypeSerive grantTypeSerive; private Map<String, Function<String,String>> grantTypeMap=new HashMap<>(); /** * Initializes the business dispatch logic instead of the if-else section * key: coupon type * value: Lambda expression */ @postconstruct public void dispatcherInit(){PostConstruct public void dispatcherInit(){ GrantTypeMap. Put (" red envelopes ", resourceId - > grantTypeSerive. RedPaper (resourceId)); GrantTypeMap. Put (" shopping ",resourceId->grantTypeSerive. Shopping (resourceId)); GrantTypeMap. Put (" qq member, "resourceId - > grantTypeSerive. QQVip (resourceId)); } public String getResult(String resourceType){//Controller Queries the coupon issuing type grantType based on the coupon type resourceType and code resourceId Function<String,String> result=getGrantTypeMap.get(resourceType); if(result! Return result.apply(resourceId); return result.apply(resourceId); return result.apply(resourceId); } return "can not find the way to issue the coupon "; }}Copy the code

If the business logic of a single if statement block has many lines, we can extract these business operations and write them as a single Service, that is:

@service public class GrantTypeSerive {public String redPaper(String resourceId){return "Red packets are issued every weekend at 9:00 ";  } public String shopping(String resourceId){return "Wednesdays at 9:00 "; } public String QQVip(String resourceId){// return "Every Monday at 0:00 "; }}Copy the code

The String resourceId parameter is used to query the database.

The result of the HTTP call:

@RestController public class GrantTypeController { @Autowired private QueryGrantTypeService queryGrantTypeService; @PostMapping("/grantType") public String test(String resourceName){ return queryGrantTypeService.getResult(resourceName); }}Copy the code

The result of the HTTP call

There are drawbacks to using Map+ functional interfaces:

Your teammate has to know lambda expressions, he won’t let himself do it

One last thought about what this article says:

1. Policy mode through interface, implementation class, logical dispatch to complete, the ** “if statement block” logic to write “a class”, easier maintenance. 2.Map+ Functional interface uses map.get (key) to replace if-else business dispatch, which can avoid the problem of class increase brought by policy mode and difficulty in overlooking the whole business logic.

Recommend 3 original Springboot +Vue projects, with complete video explanation and documentation and source code:

Build a complete project from Springboot+ ElasticSearch + Canal

  • Video tutorial: www.bilibili.com/video/BV1Jq…
  • A complete development documents: www.zhuawaba.com/post/124
  • Online demos: www.zhuawaba.com/dailyhub

【VueAdmin】 hand to hand teach you to develop SpringBoot+Jwt+Vue back-end separation management system

  • Full 800 – minute video tutorial: www.bilibili.com/video/BV1af…
  • Complete development document front end: www.zhuawaba.com/post/18
  • Full development documentation backend: www.zhuawaba.com/post/19
  • Online demos: www.markerhub.com/vueadmin

【VueBlog】 Based on SpringBoot+Vue development of the front and back end separation blog project complete teaching

  • Full 200 – minute video tutorial: www.bilibili.com/video/BV1PQ…
  • Full development documentation: www.zhuawaba.com/post/17
  • Online demos: www.markerhub.com:8084/blogs

If you have any questions, please come to my official account [Java Q&A Society] and ask me