Hable sobre la optimización de la práctica IF-ELSE en el código comercial


Prólogo: cuando trabaja con un código empresarial simple y repetitivo, debe seguir pensando y resumiendo la metodología para poder crecer

El juicio de rama IF-ELSE es una declaración de programa inevitable al escribir código comercial, que puede ayudarnos a resolver el juicio de rama, pero cuando el negocio en un método es un poco complicado, habrá muchas ramas IF-ELSE y pueden ocurrir varios juicios anidados. procesamiento de procesos.

Inserte la descripción de la imagen aquí
Este artículo no involucra buenas prácticas, solo habla del resumen de mi trabajo diario. Son seis puntos en total. Estos seis puntos no son optimización progresiva. No hay mejor ni peor. Lo importante es aplicar a un negocio específico proceso de código Elija Los métodos apropiados y simples son los más importantes.

1. Es mejor evitar el juicio de la rama

Dado que el juicio de rama es problemático, es mejor evitar el juicio de rama. Pero esto parece demasiado ideal, pero podemos evitar el juicio de rama por una lógica de juicio simple. La evasión que se menciona aquí no es un juicio de rama, pero aprenda a usar las herramientas existentes para evitar incrustar el juicio de rama en nuestro propio código comercial, como el siguiente caso compara el valor numérico, por lo que puede usar la clase de herramienta Math del JDK para manejarlo. Además, algunas operaciones de recolección también pueden ser manejadas por el kit de herramientas de recolección.

【ordinario】

 double result;
  if (value <= MIN_LIMIT) {
    
    
      result = MIN_LIMIT;
  } else {
    
    
      result = value;
  }

【mejoramiento】

double result = Math.max(MIN_LIMIT, value);
2. Minimizar el alcance de las condiciones

Minimice el alcance de las condiciones, intente presentar un código de procesamiento común, puede usar variables comunes para procesar el mismo código lógico
[ordinario]

  Result result = service.doWork();
  if (result.isSuccess()) {
    
    
      String message = "任务处理成功";
      smsService.sendMessage(user.getPhone(), message);
  } else {
    
    
      String message = "任务处理失败:" + result.getMessage();
      log.warn(message);
      smsService.sendMessage(user.getPhone(), message);
  }

【mejoramiento】

 String message;
 Result result = service.doWork();
 if (result.isSuccess()) {
    
    
     message = "任务处理成功";
 } else {
    
    
     message = "任务处理失败:" + result.getMessage();
     log.warn(message);
 }
 smsService.sendMessage(user.getPhone(), message);
3. Ubicación del filtro condicional

La ubicación del cribado condicional no está relacionada con la escalabilidad y legibilidad del código, sino con la optimización en IF-ELSE. Si hay varios juicios de selección condicionales, coloque la rama de juicio que puede filtrar la mayoría de los datos al principio, lo que ayudará a mejorar la eficiencia del procesamiento del código.

Filtre situaciones especiales con anticipación y preste más atención a la lógica empresarial central

4. Sentencias de tutor

La declaración de guardián consiste en dividir una expresión condicional compleja en varias expresiones condicionales. Por ejemplo, si se anidan varios if-elseif-else, se pueden dividir en varios ifs. Como el siguiente código

【ordinario】

 public void test () {
    
    
     if (isWeekend()) {
    
    
         if (isRest()) {
    
    
             System.out.println("看书学习");
         } else {
    
    
             System.out.println("加班");
         }
     } else {
    
    
         //这里省略了周一到周五的分支判断
     }
 }

[Optimización]
Descripción:
Hay dos puntos involucrados:
1. Reemplazar múltiples IF-ELSE anidados configurando múltiples IF. Al establecer múltiples IF, el código se verá más fácil de leer, y para la lógica de procesamiento en cada IF También puede crear un método por separado a través de la extracción de código, como el siguiente código se ve mejor

public Object test() {
    
    
    if (!isWeekend()) {
    
    
      return doSomething1();
    }
    if (isRest()) {
    
    
     return   doSomething2();
    }
    if (other()) {
    
    
     return   doSomething3();
    }
    return   doSomething4();
}

2. A través del método de protección de sentencias, filtre por adelantado 特殊情况, de modo que pueda concentrarse más en la realización de los códigos comerciales básicos.

public void test() {
    
    
    // 提前过滤掉`特殊情况`
    if (!isWeekend()) {
    
    
        System.out.println("XXX");
        return; // 提前return
    }
    //提前过滤掉`特殊情况`
    if (isRest()) {
    
    
        System.out.println("XXX");
        return; // 提前return
    }
    //更关注于 `核心业务`代码实现
     doSomething();
}
5. Seleccione la rama, prefiera usar la instrucción switch en lugar de la instrucción if-else

Enunciado if-else, cada enunciado condicional if debe estar equipado con cálculos hasta que el enunciado condicional if sea verdadero. La instrucción de cambio está optimizada para saltos, y las instrucciones de conmutador de tabla o conmutador de búsqueda se utilizan en Java para lograr una mayor eficiencia para el procesamiento de ramas de selección de múltiples constantes. Los experimentos han demostrado que si cada rama tiene la misma probabilidad de ocurrencia, las declaraciones if-else son más eficientes cuando hay menos de 5 ramas, y las declaraciones de cambio son más eficientes cuando hay más de 5 ramas.
【ordinario】

if (i == 1) {
    
    
    ...; // 分支1
} else if (i == 2) {
    
    
    ...; // 分支2
} else if (i == ...) {
    
    
    ...; // 分支3
} else {
    
    
    ...; // 分支n
}

【mejoramiento】

switch (i) {
    
    
    case 1 :
        ... // 分支1
        break;
    case 2 :
        ... // 分支2
        break;
    case ... :
        ... // 分支n
        break;
    default :
        ... // 分支n+1
        break;
}
6. La rama se modifica en un operador ternario.

Para la rama con un valor de retorno único del resultado del juicio, es relativamente simple, por lo que puede usar el operador ternario para reemplazar la rama correspondiente. Por ejemplo, compare valores numéricos, (a> = b)? A: b. Para este tipo de lógica que se puede resolver con una línea de código, también puede usar los operadores && y || en combinación.
Ordinario

String title;
if (isMember(phone)) {
    
    
    title = "会员";
} else {
    
    
    title = "访客";
}

mejoramiento

String title = isMember(phone) ? "会员" : "访客";

Nota: Para el cálculo aritmético del tipo de paquete, se debe tener cuidado para evitar el problema de punteros nulos al desempacar.

7. Utilice la estructura de datos del mapa + el modo de estrategia + el modo de fábrica para manejar negocios complejos IF-ELSE

En el código comercial real, a menudo hay casos en los que se realiza un procesamiento de lógica comercial diferente de acuerdo con un determinado Tipo, que generalmente se asocia con muchos juicios de sucursales. Además, un punto muy importante es que se considera que esta parte del negocio tiene necesidades de modificación y aumento posteriores, entonces, ¿cómo optimizar esta parte del código empresarial? Una buena referencia práctica es tratarlo a través del modo Estructura de datos del mapa + estrategia.

Para la declaración if-else de la relación de mapeo, puede usar Map para simplificarlo. Además, esta regla también se aplica a las sentencias de conmutación que simplifican la relación de mapeo y utilizan la estructura de datos del Mapa para resolver el problema de ramificación.

【ordinario】

 public static String getNameByType(String type) {
    
    
        switch (type) {
    
    
            case "A001":
                return "登录成功";
            case "B001":
                return "密码错误";
            case "C001":
                return "验证码错误";
            case "D001":
                return "短信发送失败";

        }
    }

【mejoramiento】

private static final Map<String, String> MAP = ImmutableMap.<String, String>builder()
            .put("A001", "登录成功")
            .put("B001", "密码错误")
            .put("C001", "验证码错误")
            .put("D001", "短信发送失败").build();


    public static void main(String[] args) {
    
    
        String type = "A001";
        String result = MAP.get(type);

    }

El código anterior usa Map para almacenar diferentes tipos de información, pero el código anterior es relativamente fijo. Por un lado, necesita modificar los datos del Mapa si están expandidos, y por otro lado, no es adecuado para negocios complejos Procesando.

Para este tipo de problema, puede utilizar el patrón de estrategia + método de fábrica para resolver el problema de negocios complejos y de fácil expansión.

El diseño de código detallado ya no se indica, consulte la siguiente publicación de blog para obtener más detalles:
https://juejin.cn/post/6844903974525468680

Descripción general:
1. Proporcionar una interfaz de estrategia
2. Proporcionar una clase de fábrica StrategyFactory responsable de almacenar diferentes objetos de procesamiento de ramas en el contenedor Map
3. Utilice la interfaz InitializingBean proporcionada por Spring para inyectar en el contenedor a través de StrategyFactory cuando se cargue cada clase de procesamiento comercial.
4. Según diferentes negocios, obtenga objetos obteniendo diferentes Beans para realizar un procesamiento comercial específico

Supongo que te gusta

Origin blog.csdn.net/Octopus21/article/details/114412950
Recomendado
Clasificación