2009-03-09 12 views
10

Uno de mis demonios de programación personal siempre ha sido una lógica compleja que necesita ser controlada por sentencias if (o similares). No siempre es necesariamente tan complejo, a veces tan solo unos pocos estados que deben tenerse en cuenta.¿Hay alguna herramienta para ayudar con la compleja lógica 'si'?

¿Existen herramientas o pasos que un desarrollador puede realizar durante el tiempo de diseño para ayudar a ver los 'estados' y tomar medidas para refactorizar el código para simplificar el código resultante? Estoy pensando en dibujar una matriz o algo así ...?

Respuesta

17

Recomendaría un curso básico en propositional logic por cada aspirante a programador. Al principio, la notación y las letras griegas pueden parecer desagradables para los matemáticos aversos, pero en realidad es una de las herramientas más poderosas (y frecuentemente descuidadas) en su conjunto de habilidades, y bastante simple, en el núcleo.

El basic operators, de Morgan's y other basic laws, truth tables, y la existencia de, por ejemplo, disjunctive y conjunctive normal forms fueron una revelación para mí. Antes de aprender sobre ellos, las expresiones condicionales se sentían como bestias peligrosas. Desde entonces, sé que puedo azotarlos para que se sometan cada vez que sea necesario ¡liberando la artillería pesada!

3

Verdades de verdad y pruebas unitarias: elabore las tablas (n dimensiones para n variables), y luego utilícelas como entradas para su prueba unitaria, que puede probar cada combinación de variables y verificar los resultados.

+0

Las tablas de verdad son siempre de 2 dimensiones (a menos que haya habido nuevos desarrollos?). ¿Quiere decir n columnas para n variables? –

+0

tablas de verdad multidimensionales? ¡suena emocionante! –

+1

Er ... las tablas de verdad tienen columnas para todas las variables y filas para todas las combinaciones de valores. Puede representar tantas variables como desee. – cletus

0

Divida la lógica en unidades discretas (a & & b, etc.), cada una con su propia variable. Luego compila esto usando la lógica que necesitas. Nombra cada variable con algo apropiado, para que tu declaración compleja sea bastante legible (aunque puede tomar varias líneas adicionales y algunas variables temporales).

+0

Ok, este es más o menos el enfoque que tomo, el problema es que me encuentro rellenando nuevas ramas cuando identifico la necesidad de ellas y no puedo encontrar una rama existente. Obviamente, esto da como resultado el código de spaghetti ... necesito una manera de tomar esto y 'ver la imagen más grande' –

5

Las tablas de verdad son básicamente el enfoque exhaustivo y (con un poco de suerte) resaltarán todas las posibilidades.

Puede que desee echar un vistazo a Microsoft Pex, que puede ser útil para detectar los casos de flecos que no había pensado.

+1

+1 para obtener información sobre Pex. Parece una gran herramienta. –

2

El mayor problema que he visto a lo largo de los años con IF complejos es que la gente no prueba todas las ramas. Asegúrese de escribir una prueba para cada posible rama, sin importar cuán improbable parezca que la golpee.

0

¿Alguna razón por la que no puedes manejar la lógica con las declaraciones de guardia?

2

Quizás también quiera probar Karnaugh maps, que son buenos para hasta 4 variables.

+0

me ganaste. –

+0

Los mapas de Karnaugh son buenos para eso. Es una lástima que los odie con pasión. Ellos fueron los que me convencieron de que nunca más quiero ser Ingeniero en Computación. :-) –

0

Karnaugh maps pueden ser buenas maneras de tomar información de una tabla de verdad (sugerida por Visage) y convertirlas en expresiones compactas y/o no. Estos generalmente se enseñan en un curso de lógica digital EE.

1

Si no lo has hecho ya, te sugiero que leas Code Complete. Tiene muchos consejos sobre temas como este. No tengo mi copia a mano en este momento, de lo contrario publicaría un resumen de esta sección en el libro.

4

Creo que el desarrollador pregunta cómo hacer su vida más fácil cuando se trata de código complejo.

La forma en que manejo código complejo es codificar lo más posible y elimino primero todas las negaciones. Si puede deshacerse del compuesto si coloca una parte de él arriba, entonces hágalo.

La belleza de la simplicidad es que no se necesita un libro o una clase para aprenderlo. Si puedes romperlo, hazlo. Si puede eliminar una parte, hágalo. Si no lo entiende, hágalo de manera diferente. Y plano es casi siempre mejor que anidado (¡gracias python!).

Es más sencillo de leer:

if(broken){ 
    return false; 
} 
if (simple){ 
    doit(); 
    return true; 
} 
if(complicated){ 
    divide(); 
    conquor(); 
} 
if(extra){ 
    extra(); 
} 

de lo que es para leer:

if(!broken && (simple || complicated)){ 
.... 
} 
return false; 
0

Mira la opción nuclear: Drools. Hay bastante para eso, me tomó uno o dos días de leer detenidamente la literatura solo para conocer sus capacidades. Pero si tiene aplicaciones en las que su compleja lógica de si-entonces es una parte en evolución del proyecto (por ejemplo, una aplicación con algoritmos modulares) podría ser la solución.

Cuestiones relacionadas