Eight schemes for optimizing if else code

preface

If there are many if else in the code, it is difficult to read and maintain, and it is easy to bug. Next, this paper will introduce eight schemes to optimize if else code.

Optimization scheme 1: return in advance to remove unnecessary else

If the if else code block contains a return statement, you can consider killing the redundant else by returning in advance to make the code more elegant.

Before optimization:

if (condition) {
    //doSomething
} else {
    return;
}

After optimization:

if(!condition){
    return;
}
//doSomething 

Optimization scheme 2: use conditional ternary operator

Using conditional ternary operators can simplify some if else and make the code more concise and readable

Before optimization:

int price;
if (condition) {
    price = 80;
} else {
    price = 100;
}

After optimization:

int price = condition ? 80 : 100; 

Optimization scheme 3: using enumeration

In some cases, if else logical branches can also be optimized by using enumeration. Personally, it can also be regarded as a table driven method.

Before optimization:

String OrderStatusDes;
if (orderStatus == 0) {
    OrderStatusDes = "Order not paid";
} elseif ( OrderStatus == 1 ) {
    OrderStatusDes = "Order paid";
} elseif ( OrderStatus == 2 ) {
    OrderStatusDes = "Shipped";
}
...

After optimization:

Define an enumeration first

public enum OrderStatusEnum {
      UN_PAID(0, "Order not paid"),
      PAIDED(1, "Order paid"),
      SENDED(2, "Shipped"),
      ;

      private int index;
      private String desc;
      public int getIndex() {
          return index;
      }
      public String getDesc() {
          return desc;
      }

      OrderStatusEnum(int index, String desc) {
          this.index = index;
          this.desc = desc;
      }

      OrderStatusEnum of(int orderStatus) {
          for (OrderStatusEnum temp : OrderStatusEnum.values()) {
              if (temp.getIndex() == orderStatus) {
                  return temp;
              }
          }
          return null;
      }
  }

With enumeration, the above if else logical branches can be optimized into one line of code

String OrderStatusDes = OrderStatusEnum.0f(orderStatus).getDesc();

Optimization scheme 4: merge condition expression

If a series of conditions return the same result, they can be combined into a conditional expression to make the logic clearer.

Before optimization

double getVipDiscount () {
  if (age < 18) {
      return 0.8;
  }

  if ("Shenzhen".equals(city)) {
      return 0.8;
  }

  if (isStudent) {
      return 0.8;
  }
  //do somethig
}

After optimization

double getVipDiscount(){
    if (age< 18 || "Shenzhen".equals(city)||isStudent){
        return 0.8;
    }
    //doSomthing
}

Optimization scheme 5: use Optional

Sometimes there are many if else because of non null judgment. At this time, you can use java8's Optional for optimization.

Before optimization:

String str = "jay@huaxiao";
if (str != null) {
    System.out.println(str);
} else {
    System.out.println("Null");
}

After optimization:

Optional<String> strOptional = Optional.of("jay@huaxiao");
strOptional.ifPresentOrElse(System.out::println, () -> System.out.println("Null"));

Optimization scheme 6: table driven method

Table driven method, also known as table driven, table driven method.

Table driven method is a method that enables you to find information in a table without using many logical statements (if or case) to find them.

The following demo abstracts the map into a table to find information in the map without unnecessary logical statements.

Before optimization:

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

After optimization:

Map<?, Function<?> action> actionMappings = new HashMap<>();
// Generic here ? For the convenience of demonstration, it can actually be replaced with the type you need
// initialization
actionMappings.put(value1, (someParams) -> {
    doAction1(someParams)
});

actionMappings.put(value2, (someParams) -> {
    doAction2(someParams)
});

actionMappings.put(value3, (someParams) -> {
    doAction3(someParams)
});
// Omit redundant logical statements
actionMappings.get(param).apply(someParams);

Optimization scheme 7: optimize the logical structure and let the normal process take the trunk

Before optimization:

public double getAdjustedCapital () {
    if (_capital <= 0.0) {
        return 0.0;
    }

    if (_intRate > 0 && _duration > 0) {
        return (_income / _duration) * ADJ_FACTOR;
    }
    return 0.0;
}

After optimization:

public double getAdjustedCapital () {
    if (_capital <= 0.0) {
        return 0.0;
    }

    if (_intRate <= 0 || _duration <= 0) {
        return 0.0;
    }

    return (_income / _duration) * ADJ_FACTOR;
}

Reverse the condition to make the exception exit first and keep the normal process in the main process, which can make the code structure clearer.

Optimization scheme 8: strategy mode + factory method to eliminate if else

Assuming that the demand is to process the corresponding medal services according to different medal types, the following codes are available before optimization:

String medalType = "guest";
if ("guest".equals(medalType)) {
    System.out.println("Guest Medal");
} else if ("vip".equals(medalType)) {
    System.out.println("Member Medal");
} else if ("guard".equals(medalType)) {
    System.out.println("Show the guardian Medal");
}
...

First, we abstract each conditional logic code block into a common interface to obtain the following code:

//Medal interface
public interface IMedalService {
    void showMedal ();
    String getMedalType ();

}

We define the corresponding policy implementation class according to each logical condition, and the following code can be obtained:

//Guardian medal policy implementation class
public class  GuardMedalServiceImpl implements IMedalService {
    @Override
    public void showMedal() {
        System.out.println("Show the guardian Medal");
    }

    @Override
    public String getMedalType() {
        return "guard";
    }

}

//Guest medal strategy implementation class
public class GuestMedalServiceImpl implements IMedalService {
    @Override
    public void showMedal() {
        System.out.println("Guest Medal");
    }

    @Override
    public String getMedalType() {
        return "guest";
    }
}

//VIP Medal strategy implementation class
public class VipMedalServiceImpl implements IMedalService {

    @Override
    public void showMedal() {
        System.out.println("Member Medal");
    }

    @Override
    public String getMedalType() {
        return "vip";
    }

}

Next, we define the policy factory class to manage these medal implementation policy classes, as follows:

//Medal service industry
public class MedalServicesFactory {

    private static final Map<String, IMedalService> map = new HashMap<>();

    static {
        map.put("guard", new GuardMedalServiceImpl());
        map.put("vip", new VipMedalServiceImpl());
        map.put("guest", new GuestMedalServiceImpl());
    }

    public static IMedalService getMedalService(String medalType) {
        return map.get(medalType);
    }

}
...

After using the policy + factory mode, the code becomes much simpler, as follows:

public class Test {

    public static void main(String[] args) {
        String medalType = "guest";
        IMedalService medalService = MedalServicesFactory.getMedalService(medalType);
        medalService.showMedal();
    }

}

 

reference resources: https://mp.weixin.qq.com/s/tK0r0jNbYpvezNqWft5ydA

Tags: Java

Posted on Mon, 08 Nov 2021 22:20:55 -0500 by fabrice