How to reduce the if-else statement in your code, write elegant code,

  • Actual projects, tend to have a lot of if-else statements variety of logic verification, calibration parameters and so on, a lot of if-else, the statement makes the code becomes bloated and bad maintenance, this article combined with my own experience , reduced if-else statement given several options, each suited to different scenarios, for your reference, if you have questions or suggestions, please point out promptly;

A Option One: ternary expression:

      //使用if-else语句
      String str;
      if (user.getAge()>18){
            str="已成年";
      }else {
            str="未成年";
      }
      //使用三元表达式
      str=user.getAge()>18?"成年":"未成年";
复制代码

Advantages: simplify the code, the code to reduce bloated

Cons: conditions applicable to relatively small, relatively simple logic judgment of the case, when if conditions are relatively long, the code will be too bloated, is not conducive to read and maintain

Two Option II: Optional use of packaging JDK1.8

Optional JDK1.8 class is one of the new features, functionality is very powerful, how the following example describes the reduction of an if statement

        //使用 if 语句
        User user=userService.findById(userId);
        if (null==user){
            throw new RuntimeException("参数错误,未找到指定用户");
        }
        //使用Optional类包装
        Optional.ofNullable(userService.findById(userId)).orElseThrow(()->new RuntimeException("参数错误,未找到指定用户"));
复制代码

The benefits of using Optional class is further characterized by the Optional packaged containers can be used in functional programming associated method, for example, filter (), map () method, and the like, and screening for the conversion of our business logic and objects, such codes have greatly increased flexibility, for example:

        //筛选出大于18岁的用户,如果没有就抛出异常
        Optional.ofNullable(userService.findById(userId))
                .filter(x->x.getAge()>18)
                .orElseThrow(()->new RuntimeException("参数错误,未找到指定用户"));
复制代码

Code is simple and a lot of it

Advantages: more complex logic can be determined

Disadvantages: Analyzing conditions should not be too excessive condition judgment should not be used in this manner

Three Option Three: Using assertions Assert class

In the Spring of org.springframework.util package, it built Assert Assert Classes, the conditional expression for determining

    //使用断言类
        User user=userService.findById(userId);
        Assert.notNull(user, "参数错误,未找到指定用户");
复制代码

Method assertion class return value is void, we do assert that class commonly used in Junit unit testing, unit testing because the methods are no parameters, the method returns no value, and therefore assert Assert class used to test the return value of a program for compliance with our expectations could not be better

Advantages: determining a number of built-in methods, e.g. notNull, notEmpty, equal or the like, the code readability, a program and the relative Scheme II can be applied to more branch judgment;

Disadvantage: When assertion failures only exception is IllegalArgumentException (message), suitable for a relatively simple determination logic

Four Option 4: Use @Validate annotation for verification of the parameters determined

In business development, form validation performed, and when the reference check, they tend to use interface, a large number of if-else statements do check parameters, so that the code will be particularly bloated and redundant, so we can use the packaged library to check, in the JSR303 specification, defines annotations @Valid parameter check, a broad framework vendors such as spring, based on the JSR303 specification, provide their own implementations, and provides many advanced features, such as @Validated is @Valid variant;

The following excerpt from org.springframework.validation.annotation in @Validated documentation comments annotations

Variant of JSR-303's {@link javax.validation.Valid}, supporting the specification of validation groups. Designed for convenient use with Spring's JSR-303 support but not JSR-303 specific.

   //接口定义
    @RequestMapping("/update")
       public void updateUser(@RequestBody @Validated User user) {
           userService.updateUser(user);
   }
   //参数校验
   public class User implements Serializable {
       @NotNull(message = "参数不能为空")
       private Integer id;
       
       @NotBlank(message = "参数不能为空")
       private String username;
       
       @NotBlank(message = "参数不能为空")
       private String password;
       
       @NotEmpty(message = "参数不能为空")
       private List<String> desc;
       
       //这里可以通过正则来校验时间格式是否正确
       @NotNull(message = "参数不能为空")
       @Pattern(regexp = "xxxx",message ="时间格式不符合规范" )
       private Date date;
   }
复制代码

Note: If the check fails @Validated parameter, throws an exception, if the reception anomaly code, in the parameter of the interface, the BindingResult add parameters to add this class, then, this exception will be encapsulated in the class , does not throw out, we can call this class API to get specific exception information, then we can anomaly information to customize our own response

   public ModelAndView save(@Validated CategoryForm form,
                            BindingResult bindingResult,
                            Map<String, Object> map) {
       if (bindingResult.hasErrors()) {
           map.put("msg", bindingResult.getFieldError().getDefaultMessage());
           map.put("url", "/sell/seller/category/index");
           return new ModelAndView("common/error", map);
       }
   }
复制代码

Advantages: very suitable in a particular environment as interface to check the parameters

Disadvantages: big limitations, can not be used in business logic

V. Program Five: Strategy Mode

Strategy Mode is one of design patterns, the original intention of design patterns to solve specific problems in the code exists, the definition of Baidu, the strategy pattern:

In Strategy Mode (Strategy Pattern), a class of behavior or algorithm can be changed at runtime. This type of design pattern belongs behavioral patterns. In strategy mode, we create the context object represents the behavior of various objects and a policy change with the change of policy objects. Policy object to change the algorithm execution context object.

Is simply the algorithm (strategy) and the object has been pre-defined, with the change of parameters passed to choose a different algorithm (strategy), more specific semantics is (if - else) in accordance with the conditions do not selectively ? the implementation of different code it and I was repeatedly used in the development of the strategy pattern to reconstruct the complex if-else logic, time-tested, greatly improving the elegance of the code;

Here is an example in the development of my business, how to use the strategy pattern in Spring usage scenarios: demand: more than one interface, in response to the same, according to the type of parameters passed, use different strategies;

  //策略上下文
  @Configuration
  public class StrategyContext{
      
      @Resource
      public Map<String,Strategy> strategyMap;
      
      public List<Resp> doGet(String type){
          Strategy strategy =strategyMap.get(type);
          retun strategy.doStrategy();
      }
  }
  //配置策略
  @Configuration
  public class StrategyConfig{
      @Resource
      public ServiceImpl1 serviceImpl1
      
      @Resource
      public ServiceImpl2 serviceImpl2
      
      @Bean
      public Map<String,Strategy> getMap(){
          Map<String,Strategy> strategyMap =new HashMap()
          strategyMap.put("1",new ServiceImpl1());
          strategyMap.put("2",new ServiceImpl2());
          return strategyMap
      }
  //策略接口类
  public interface Strategy{
      List<Resp> doStrategy();
  }
  //具体策略1
  public class ServiceImpl1 implements Strategy{
      //重写策略方法
      @Override
      publicList<Resp> doStrategy(){
          ...
      }
  }
   //具体策略2
  public class ServiceImpl2 implements Strategy{
      //重写策略方法
      @Override
      publicList<Resp> doStrategy(){
          ...
      }
  }
  //在Controller层的代码中注入策略上下文
  public class AAAController{
      @Autowired
      public StrategyContext context;
      
      public List<Resp> getXXX(String type){
          //设计模式-策略模式
          return context.doGet(type)
      }
      
  }
复制代码

Advantages: For complex business logic, code scalability

Disadvantage: usually factory mode or with the use Flyweight

Guess you like

Origin juejin.im/post/5d87137be51d453b7403fa5f