First, the model of ridicule

The project development cycle is short, the iteration speed is fast, after a long time, the code may be filled with a large number of if/else, layer by layer nesting, so that it is impossible to understand the logic of the code in a short time, as time goes by, the person who takes over may really spit lotus!

// Like this, step by step into the pyramid
if (condition1) {
    action1();
    if (condition2) {
        action2();
        if (condition3) {
            action3();
            if(condition4) { action4(); }}}}Copy the code

Whenever we take over an old project like this, we may quietly turn on the joke mode

1. Why does this project feel like it has no design and does what you want

2. This is all logic, no comment, look at NM

3. Logic nesting so much, look at me, who wrote the garbage code?

4. I will bear with it. No, I will run away too.

Who doesn’t want to be a good ape? Will the boss give you a chance? “Three days, no more, on Monday.”

! [other] [1]

So too much if… Else, how can we optimize, make our program look a little cleaner? Also for the follow-up of the project, lighten the burden, less ridicule.

Second, solutions

Return early

To put it bluntly, the judgment condition is reversed, so that the program does not meet the condition is returned in advance, the code will be clearer in the logical expression, see the following code:

if (condition) {
   // do something
} else {
  return xxx;
}

// Change to judge first! Condition, get rid of the else
if(! condition) {return xxx;
 
} 
// do something
Copy the code

Optional

Optional is mainly used for non-null judgments and is a new feature in JDK8, so it is not used very much.

// If the logon user is empty, execute action1; otherwise, execute action 2
/ / before use
if (user == null) {
    //do action 1
} else {
    //do action2
}
/ / after use
Optional<User> userOptional = Optional.ofNullable(user);
userOptional.map(action1).orElse(action2);

// Use Optional optimizations to make non-null validation more elegant, indirectly reducing if operations
Copy the code

Assert

Assert can help you validate various parameters, such as strings not being empty. Many other framework libraries, such as Spring and Apache Commons, provide utility classes to implement this common functionality so that you don’t have to write your own if… The else. Such as:

Assert.hasText(param.getType(), "Parameter type cannot be null");
Copy the code

For Spring Assert classes, check out docs. Spring-fram…

Table driven method

Logical expression pattern fixed if/else code, can be mapped, the logical expression in the form of the table, and then use the table to find a corresponding input processing function, use this processing function for calculation. Such as:

if (param.equals(value1)) {
    doAction1(someParams);
} else if (param.equals(value2)) {
    doAction2(someParams);
} else if (param.equals(value3)) {
    doAction3(someParams);
}
Copy the code

After table driven reconstruction

Map<? , Function<? > action> actionMappings =new HashMap<>();

/ / initialization
actionMappings.put(value1, (someParams) -> { doAction1(someParams)});
actionMappings.put(value2, (someParams) -> { doAction2(someParams)});
actionMappings.put(value3, (someParams) -> { doAction3(someParams)});

// omit null judgment
actionMappings.get(param).apply(someParams);
Copy the code

Table mappings can be centralized or decentralized, where each processing class registers itself, or through configuration files.

event-driven

By correlating different event types and corresponding processing mechanisms, complex logic can be realized and decoupled at the same time. In theory, event-driven can be considered a type of table driver, but in practice, event-driven differs from the table driver mentioned earlier in several ways. The main performance is as follows:

Table drivers are usually one-to-one; Event-driven is usually one-to-many;

In table drivers, triggering and execution are usually strongly dependent; In event driven, triggering and execution are weakly dependent

It is the differences between the two that lead to different application scenarios. To be specific, event-driven can be used to trigger functions such as inventory, logistics, points and so on when order payment is completed.

Annotation driven

Define the conditions under which a method is executed through Java annotations (or similar mechanisms in other languages). At program execution, the method is decided whether to call it by comparing the conditions defined in the participating annotations to whether they match. Annotations, driven to the use of this pattern can be seen in many frameworks, for example, we often use in the Spring, the specific instances, everyone can refer to: www.cnblogs.com/houzheng/p/…

The strategy pattern

For the scenarios of the following four strategies, we adopt two optimization schemes as examples

if (strategy.equals("fast")) {
  //do FAST action
} else if (strategy.equals("normal")) {
  //do NORMAL action
} else if (strategy.equals("smooth")) {
  //do SMOOTH action
} else if (strategy.equals("slow")) {
  //do SLOW action
}
Copy the code

polymorphism

interface Strategy {
  void run(a) throws Exception;
}

class FastStrategy implements Strategy {
    @Override
    void run(a) throws Exception {
        //do FAST action}}class NormalStrategy implements Strategy {
    @Override
    void run(a) throws Exception {
         //do NORMAL action}}class SmoothStrategy implements Strategy {
    @Override
    void run(a) throws Exception {
        //do SMOOTH action}}class SlowStrategy implements Strategy {
    @Override
    void run(a) throws Exception {
        //do SLOW action}}// Call pseudocode (map objects to store policies, reflect calls, give spring to get beans, etc.)
Strategy strategy = map.get(param);
strategy.run();
Copy the code

The enumeration

Define methods in enumerations and break down logical calls

public enum Strategy {
    FAST {
        @Override
        void run(a) {
            //do FAST action
        }
    },
    NORMAL {
        @Override
        void run(a) {
            //do NORMAL action
        }
    },

    SMOOTH {
        @Override
        void run(a) {
            //do SMOOTH action
        }
    },

    SLOW {
        @Override
        void run(a) {
            //do SLOW action}};abstract void run(a);
}

// Call pseudocode
Strategy strategy = Strategy.valueOf(param);
strategy.run();
Copy the code

Chain of Responsibility model

When the if… Conditional expressions in the else are flexible, and when the data in the condition cannot be abstracted into a table and judged in a uniform way, the judgment of the condition should be given to each functional component. These components are connected in series in the form of chain to form a complete function, which is suitable for scenarios where the conditional expression is flexible and changeable without a unified form.

Implementation and Examples

/ / before the refactoring
public void handle(request) {
    if (handlerA.canHandle(request)) {
        handlerA.handleRequest(request);
    } else if (handlerB.canHandle(request)) {
        handlerB.handleRequest(request);
    } else if(handlerC.canHandle(request)) { handlerC.handleRequest(request); }}/ / after the refactoring
public void handle(request) {
  handlerA.handleRequest(request);
}

public abstract class Handler {
  protected Handler next;
  public abstract void handleRequest(Request request);
  public void setNext(Handler next) { this.next = next; }}public class HandlerA extends Handler {
  public void handleRequest(Request request) {
    if (canHandle(request)) doHandle(request);
    else if(next ! =null) next.handleRequest(request); }}Copy the code

Third, to express their opinions

If /else, my husband likes if/else, hahaha

Dao Friend B: I don’t write more if/else, so that the code doesn’t look convoluted. How can I reflect my workload

Friend C: I have written so much code, you just told me to optimize this, I am tired

D: Why not switch? Switch is much more comfortable than if/else

Dao Friend E: I was too busy and worked too much overtime, so I refused to speak…

! [other] [2]