The policy pattern is used in conjunction with Spring

We often encounter a lot of if else cases in the project. For example, there is a type in the front paragraph, and the data processing process logic is different for different types. What should we do in normal cases? It would look something like this:

If (" aa ". The equals (type)) {/ / a treatment} else if (" bb ". The equals (type)) {/ / it is a processing} else if () {} else if () {} else if () {}Copy the code

Of course, if we write it ourselves, we can read it by ourselves, it doesn’t matter, but if we let other people read it, it must be like this:

But we don’t want to write code like this, and then some people will say :” Well, at the beginning, there is not so much logic in the requirements given by the product. As the requirements of the product are iterated, the project is short of time and we have to use the original code if else, we are also innocent!”

There is no way to avoid this, so one way is to rely on your project experience to know that this will happen later, and the other way is to refactor the code when there is a lot of logical judgment (the most frustrating).

So with that said, I’m going to show you how to solve this if else problem where I’m using the strategy mode, okay

The finished code is shown in the Controller layer

@postmapping ("/action") public String action(@requestBody ActionVO ActionVO){PostMapping("/action") public String action(@requestBody ActionVO ActionVO) Himself with the love you ActionHandler ActionHandler = actionHandlerFactory. GetRoutMap () get (actionVO. GetType ()); if(actionHandler! =null){ actionHandler.handler(actionVO); } return "success";Copy the code
public class ActionHandlerFactory { private static Map<Byte, ActionHandler> ROUT_MAP; @Autowired private TeacherActionHandler teacherActionHandler; @Autowired private UserActionHandler userActionHandler; @PostConstruct private void init(){ ROUT_MAP= ImmutableMap.<Byte,ActionHandler>builder() .put(ActionEnum.USER.getType(),userActionHandler) .put(ActionEnum.TEACHER.getType(),teacherActionHandler).build(); } public Map<Byte,ActionHandler> getRoutMap(){ return ROUT_MAP; }}Copy the code

There is no “if else”, but instead we put the handler that actually executes the code in the map.

Do you want to be more elegant if you want to be more elegant I’ll take you onThe inheritance structure for code classes that perform business logic, like mine, looks like this

public abstract class ActionHandler implements RequestHandler<ActionVO> {

  @Override
  public void handler(ActionVO actionVO) {
    read(actionVO);
    write(actionVO);
    insert(actionVO);
  }

  @Override
  public void write(ActionVO actionVO) {

  }

  @Override
  public void read(ActionVO actionVO) {

  }

  public abstract void insert(ActionVO actionVO);


}
Copy the code

We’re using a template pattern here so that our actual business logic execution class just inherits the ActionHandler and overrides the methods that it wants

Public class UserActionHandler extends ActionHandler{@override public void insert(ActionVO ActionVO) System.out.println("im user"); } @Override public void write(ActionVO actionVO) { super.write(actionVO); Override public void read(ActionVO ActionVO) {super.read(ActionVO); // Own logic kaka is dry}Copy the code
public interface RequestHandler<T> {

  public void handler(T t);

  public void write(T t);

  public void read(T t);

Copy the code

The jar introduced by the demo is included

<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId>  </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> < version > 3.4 < / version > < / dependency > < the dependency > < groupId > org.apache.com mons < / groupId > < artifactId > Commons - dbcp2 < / artifactId > < version > 2.1.1 < / version > < / dependency > < the dependency > <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> < the groupId > org. Mybatis. Spring. The boot < / groupId > < artifactId > mybatis - spring - the boot - starter < / artifactId > < version > 2.1.4 < / version >  </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <! -- https://mvnrepository.com/artifact/com.google.guava/guava --> <dependency> <groupId>com.google.guava</groupId> < artifactId > guava < / artifactId > < version > 21.0 < / version > < / dependency > < the dependency > <groupId>org.springframework.restdocs</groupId> <artifactId>spring-restdocs-mockmvc</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> The < version > 1.1.10 < / version > < / dependency > < / dependencies >Copy the code

By using the above two design patterns, we can see if the code is more elegant and easier to read, and only need to change the handler of each module’s business logic in the future, without affecting the other code.

That’s my personal understanding hahaha

If there is anything wrong, welcome to give me a message to correct!