• In actual project, often have a lot of the if – else statements for a variety of logic calibration, parameter calibration, and so on, a lot of the if – else, statements make it difficult to maintain the code become bloated and, combined with my own experience, this article is to reduce the if – else give the following solutions, respectively applicable to different scenarios, for your reference, if you have any questions or Suggestions, please point out in time;

I. Scheme 1: Using ternary expressions:

      // Use if-else statements
      String str;
      if (user.getAge()>18){
            str="Come of age";
      }else {
            str="Minor";
      }
      // Use ternary expressions
      str=user.getAge()>18?"Adult":"Minor";
Copy the code

Advantages: Simplify code and reduce code bloat

Disadvantages: Applicable to the situation with few conditions and simple logical judgment. When there are too many if conditions, the code will be too bloated, which is not conducive to reading and maintenance

Solution 2: Use Optional class packaging in JDK1.8

The Optional class is one of the new features in JDK1.8. The following example describes how to reduce if statements

        // Use the if statement
        User user=userService.findById(userId);
        if (null==user){
            throw new RuntimeException("Parameter error, user not found");
        }
        // Use the Optional class wrapper
        Optional.ofNullable(userService.findById(userId)).orElseThrow(()->new RuntimeException("Parameter error, user not found"));
Copy the code

Another advantage of using Optional class is that after wrapping as Optional container, you can use the related methods of functional programming, such as filter(),map() method, etc., to filter and transform logic and objects in our business, which greatly increases the flexibility of code. For example:

        // Filter out users older than 18, if not, throw an exception
        Optional.ofNullable(userService.findById(userId))
                .filter(x->x.getAge()>18)
                .orElseThrow(()->new RuntimeException("Parameter error, user not found"));
Copy the code

Is the code a lot cleaner

Advantages: Can be more complex logical judgment

Disadvantages: condition judgment should not be too much, too much condition judgment should not be used in this way

Scenario 3: Use the Assert class

The Assert assertion class is built into Spring’s org.Spring Framework. util package for determining conditional expressions

    // Use an assertion class
        User user=userService.findById(userId);
        Assert.notNull(user, "Parameter error, user not found");
Copy the code

The Assert class is often used in Junit unit tests. Since unit tests use methods that have no arguments and no return value, the Assert class is a great way to test whether a program returns the values we expect

Advantages: built-in a lot of judgment methods, such as notNull,notEmpty,equal and other methods, the code is readable, compared with scheme 1 and 2, can be applied to more judgment branches;

Disadvantages: When an assertion fails, the exception can only be IllegalArgumentException(message), which is suitable for simpler logical judgments

Scheme 4: Use @validate annotation to judge input parameter verification

In the enterprise development, to form validation, as well as the interface into the parameter calibration, tend to use a lot of the if – else do parameter calibration, such code will appear particularly bloated and redundancy, so we can use packaging good libraries to check, in JSR – 303 specification, defines the annotation @ Valid parameters calibration, a big frame manufacturers such as s Pring, based on the JSR303 specification, provides its own implementation and many advanced functions. For example, @validated is a variant of @valid.

The following excerpt from org. Springframework. Validation. @ Validated annotations in the annotation of documentation comments

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.

   // Interface definition
    @RequestMapping("/update")
       public void updateUser(@RequestBody @Validated User user) {
           userService.updateUser(user);
   }
   // Check parameters
   public class User implements Serializable {
       @NotNull(message = "Parameters cannot be empty.")
       private Integer id;
       
       @NotBlank(message = "Parameters cannot be empty.")
       private String username;
       
       @NotBlank(message = "Parameters cannot be empty.")
       private String password;
       
       @NotEmpty(message = "Parameters cannot be empty.")
       private List<String> desc;
       
       // We can use the re to verify that the time format is correct
       @NotNull(message = "Parameters cannot be empty.")
       @Pattern(regexp = "xxxx",message ="Time format not conforming to specification" )
       private Date date;
   }
Copy the code

Note: If the verification of the @ parameter fails, an exception will be thrown. If you need to receive an exception in the code, you can add the parameter BindingResult to the interface parameter. After adding this class, the exception will be encapsulated in this class and will not be thrown out Information, and then we can customize our own response based on the exception information

   public ModelAndView save(@Validated CategoryForm form, BindingResult bindingResult, Map
       
         map)
       ,> {
       if (bindingResult.hasErrors()) {
           map.put("msg", bindingResult.getFieldError().getDefaultMessage());
           map.put("url"."/sell/seller/category/index");
           return new ModelAndView("common/error", map); }}Copy the code

Advantages: Very suitable for checking interface input parameters in a specific environment

Disadvantages: Too limited to be used in business logic

5. Plan 5: Strategic mode

The strategic pattern is one of the design patterns. The original intention of the design pattern is to solve a specific problem in the code. Here is the definition of the strategic pattern:

In the Strategy Pattern, the behavior of a class or its algorithm can be changed at run time. This type of design pattern is behavioral. In the policy pattern, we create objects that represent various policies and a context object whose behavior changes as the policy object changes. The policy object changes the execution algorithm of the context object.

In simple terms, the algorithm (policy) and the object are already defined in advance, and different algorithms (policy) are selected as the parameters are passed in. More specific semantics are not required to execute different code according to different conditions (if–else). In my development, I also used the strategy mode repeatedly to reconstruct the complex if-else logic judgment, which is successful every time, greatly improving the elegance of the code;

Requirements: Multiple interfaces with the same response, using different policies depending on the type of parameter passed in;

  // Policy context
  @Configuration
  public class StrategyContext{
      
      @Resource
      public Map<String,Strategy> strategyMap;
      
      public List<Resp> doGet(String type){ Strategy strategy =strategyMap.get(type); retun strategy.doStrategy(); }}// Configure the policy
  @Configuration
  public class StrategyConfig{
      @Resource
      public ServiceImpl1 serviceImpl1
      
      @Resource
      public ServiceImpl2 serviceImpl2
      
      @Bean
      public Map<String,Strategy> getMap(a){
          Map<String,Strategy> strategyMap =new HashMap()
          strategyMap.put("1".new ServiceImpl1());
          strategyMap.put("2".new ServiceImpl2());
          return strategyMap
      }
  // Policy interface class
  public interface Strategy{
      List<Resp> doStrategy(a);
  }
  // Specific strategy 1
  public class ServiceImpl1 implements Strategy{
      // Override the policy method
      @Override
      publicList<Resp> doStrategy(a){... }}// Specific strategy 2
  public class ServiceImpl2 implements Strategy{
      // Override the policy method
      @Override
      publicList<Resp> doStrategy(a){... }}// Inject the policy context into the Controller layer code
  public class AAAController{
      @Autowired
      public StrategyContext context;
      
      public List<Resp> getXXX(String type){
          // Design mode - Policy mode
          return context.doGet(type)
      }
      
  }
Copy the code

Advantages: Suitable for complex business logic, code scalability

Disadvantages: Usually used in conjunction with factory or premium mode