2011-06-30 23 views
6

Actualmente estoy trabajando en un poco de código que (creo) requiere bastantes declaraciones incrustadas. ¿Hay algún estándar para cuántas instrucciones if para incrustar? La mayoría de mis búsquedas en Google han revelado cosas relacionadas con la excelencia ... no sé por qué.¿Existe tal cosa como demasiadas sentencias if if?

Si hay un estándar, ¿por qué? ¿Es para legibilidad o para mantener el código funcionando sin problemas? En mi opinión, tiene sentido que sea principalmente para la legibilidad.

Un ejemplo de mi si-estructura:

if (!all_fields_are_empty): 
    if (id_search() && validId()): 
     // do stuff 
    else if (name_search): 
     if (name_exists): 
      if (match < 1): 
       // do stuff 
     else: 
      // do stuff 
    else if (name_search_type_2): 
     if (exists): 
      if (match < 1): 
       // do stuff 
     else: 
      // do stuff 
else: 
    // you're stupid 

He oído que hay un límite a 2-3 anidado for/while, pero ¿hay alguna norma para las sentencias if-?

Actualización: Tengo algunos años en mi haber. Por favor, no use tantas declaraciones if. Si necesita tantos, su diseño probablemente sea malo. Hoy, ME ENCANTA cuando puedo encontrar una forma elegante de hacer estas cosas con un mínimo de declaraciones if o switch casos. El código termina siendo más limpio, más fácil de probar y más fácil de mantener. Normalmente.

+0

duplicado posible: http://stackoverflow.com/questions/4610489/maximum-number-of-nested-conditions-allowed –

+0

No estoy pidiendo cuántos es el máximo, que estoy preguntando cuál es la norma está entre los programadores. – Cody

+1

No hay un máximo "estándar" entre los programadores. Cada situación tiene su propio máximo anidado. Por ejemplo, si tiene un código matemático pesado que hace algunos cálculos horribles, fácilmente iría con 15 if anidados sin problemas, si hubiera un comentario que lo explique todo cerca. Sin embargo, si partes de ese código son reutilizables, trataría de dividirlos de la manera en que podría reutilizarlo. – bezmax

Respuesta

4

Técnicamente, no tengo conocimiento de ninguna limitación para anidar.

Podría ser un indicador de diseño deficiente si te encuentras yendo muy profundo.

Parte de lo que publicaste parece que se puede servir mejor como una declaración case.

Me preocuparía la legibilidad y el mantenimiento del código para la siguiente persona, lo que realmente significa que será difícil, incluso para la primera persona (usted), hacerlo bien desde el principio.

edición:

También puede considerar la posibilidad de una clase que es algo así como SearchableObject(). Podría hacer una clase base de esto con funcionalidad común, luego heredar para ID, Nombre, etc., y este bloque de control de nivel superior se simplificaría drásticamente.

0

El único límite técnico para el número de bloques if/else anidados en Java probablemente será el tamaño de su pila. El estilo es otro asunto.

Por cierto: ¿Qué pasa con los dos puntos?

+0

Acabo de tipear algo muy rápido como un ejemplo de lo que era mi estructura if. Parte de mi experiencia de pitón que sale, supongo. – Cody

5

No creo que haya un límite, pero no recomendaría encajar más los dos: es demasiado difícil de leer, difícil de depurar y difícil de probar. Considere echar un vistazo a un par de grandes libros como Refactoring, Design Patterns, y tal vez Clean Code

1

Técnicamente puede tener tantas como quiera, pero si tiene muchas, puede hacer que el código sea rápidamente ilegible.

lo que normalmente haría es algo así como:

if(all_fields_are_empty) { 
    abuseuser; 
    return; 
} 

if(id_search() && validId()) { 
    //do stuff 
    return; 
} 

if(name_search) 
{ 
    if(name_exists) 
    //do stuff 
    return 
    else 
    //do stuff 
    return 
} 

Estoy seguro de que obtiene la imagen

7

Como se mencionó Randy, la causa de este tipo de código es en la mayoría de casos, los malos diseño de una aplicación. Usualmente trato de usar clases de "procesador" en tu caso.

Por ejemplo, dado que hay algún parámetro genérico denominado "operación" y 30 operaciones diferentes con diferentes parámetros, se puede hacer una interfaz:

interface OperationProcessor { 
    boolean validate(Map<String, Object> parameters); 
    boolean process(Map<String, Object> parameters); 
} 

luego implementar una gran cantidad de procesadores para cada operación que necesita, por ejemplo:

class PrinterProcessor implements OperationProcessor { 
    boolean validate(Map<String, Object> parameters) { 
     return (parameters.get("outputString") != null); 
    } 
    boolean process(Map<String, Object> parameters) { 
     System.out.println(parameters.get("outputString")); 
    } 
} 

El siguiente paso - que registra todos los procesadores en alguna matriz cuando se inicializa la aplicación:

public void init() { 
    this.processors = new HashMap<String, OperationProcessor>(); 
    this.processors.put("print",new PrinterProcessor()); 
    this.processors.put("name_search", new NameSearchProcessor()); 
    .... 
} 

Así que su principal método se convierte en algo parecido a esto:

String operation = parameters.get("operation"); //For example it could be 'name_search' 
OperationProcessor processor = this.processors.get(operation); 
if (processor != null && processor.validate()) { //Such operation is registered, and it validated all parameters as appropriate 
    processor.process(); 
} else { 
    System.out.println("You are dumb"); 
} 

Por supuesto, esto es sólo un ejemplo, y su proyecto requeriría un enfoque poco diferente, pero supongo que podría ser similar a lo que he descrito.

0

tl; el Dr. En realidad, no quiero más de 10-15 caminos aunque uno u otro método

Lo que su esencia se refiere a que aquí es Cyclomatic complexity.

La complejidad ciclomática es una métrica de software (medida), utilizada para indica la complejidad de un programa. Es una medida cuantitativa de el número de rutas linealmente independientes a través del código fuente del programa. Fue desarrollado por Thomas J. McCabe, Sr. en 1976.

De modo que cada enunciado si es potencialmente una nueva ruta a través de su código y aumenta su complejidad Cyclomatic. Hay herramientas que medirán esto para usted y áreas con mucha luz de alta complejidad para posibles refactorizaciones.

¿Hay algún estándar en la cantidad de sentencias if para incrustar?

Sí y no. En general se considera (y el propio McCabe argumentó) que una complejidad Cyclomatic de más de 10 o 15 es demasiado alta y una señal de que el código debe ser refactorizado.

Una de las aplicaciones originales de McCabe era limitar la complejidad de las rutinas durante el desarrollo del programa; recomendó que los programadores cuenten la complejidad de los módulos que están desarrollando y los dividan en módulos más pequeños siempre que la complejidad ciclomática de exceda el 10. [2] Esta práctica fue adoptada por la metodología de Ensayo estructurado NIST , con la observación de que desde la publicación original de McCabe , la cifra de 10 había recibido evidencia corroborante sustancial, pero que en algunas circunstancias es puede ser apropiado relajar la restricción y permitir módulos con una complejidad de tan alta como 15.Como la metodología reconoció que eran razones ocasionales para ir más allá del límite acordado, formuló su recomendación como: "Para cada módulo, limite complejidad ciclomática al [límite acordado] o brinde una explicación por escrito de por qué se excedió el límite. "[7]

Sin embargo, esta no es una regla realmente difícil y puede descartarse en algunas circunstancias. Consulte esta pregunta What is the highest Cyclomatic Complexity of any function you maintain? And how would you go about refactoring it?.

¿por qué? ¿Es para legibilidad o para mantener el código funcionando más sin problemas?

Básicamente esto es para facilitar la lectura, lo que debería hacer que su código funcione sin problemas. Para citar Martin Fowler

Cualquier tonto puede escribir el código que una computadora puede entender. Los buenos programadores de escriben códigos que los humanos pueden entender.