¿Mi código debe estar SECADO o ser legible si no puede ser ambos?

14

Estoy escribiendo el código Ruby para un simple ejercicio de encriptación y con frecuencia me he encontrado con este dilema (el ejercicio es un cifrado en solitario si es que debes saberlo). Se trata de si debo eliminar mi lógica con variables descriptivas y declaraciones de un solo paso que hacen que la función sea legible en lugar de una declaración concisa, incluso densa, que elimine la repetición y / o minimice las oportunidades de errores.

Mi ejemplo más reciente: mi programa toma entrada, y debido a las rígidas pautas de formato, puede determinar fácilmente si la entrada debe estar encriptada o desencriptada. Para simplificar, una vez que la clave de encriptación y el mensaje se convierten / generan para ser compatibles, se trata de restar la clave del mensaje encriptado o agregar la clave a un mensaje sin cifrar, para obtener la salida deseada (piense en la clave como encriptación, mensaje + cifrado = código; código - cifrado = mensaje). La posición DRY me dice que debo convertir mi mensaje cifrado de manera diferente a mi mensaje no cifrado, de modo que la función que toma la clave de cifrado y la aplica al mensaje nunca debe distinguirse. Descubrí que esto significa que necesito algunas instrucciones if anidadas en la función, pero la lógica parece ser sólida. Este código, sin embargo, no es fácil de leer. Esto requeriría algunos comentarios para ser claro.

Por otro lado, podría escribir dos funciones diferentes que se llaman en función de un indicador que se establece cuando la aplicación determina el cifrado o descifrado. Esto sería más fácil de leer pero duplicaría la función de alto nivel de aplicar la clave de cifrado a un mensaje (haciendo que se cifre o descifre).

¿Debo inclinarme hacia un código legible o un código conciso? ¿O me he perdido otra forma de obtener esta funcionalidad y satisfacer ambos principios? ¿Es una posición a lo largo de una escala en la que uno debe considerar el propósito del proyecto y tomar las mejores decisiones para servir a ese propósito?

Hasta ahora, tiendo a enfatizar el código DRY conciso sobre el código legible.

    
pregunta lutze 10.04.2013 - 03:47
fuente

7 respuestas

19

DRY es una guía, no una religión. Aquellos que lo llevan al punto de SECAR por encima de todo lo demás, lo han llevado demasiado lejos.

En primer lugar, el código utilizable es primordial. Si el código no es útil y utilizable, no lo es ... y no tiene ningún sentido escribirlo en primer lugar.

En segundo lugar, algún día, alguien tendrá que mantener su código. Si su código no es mantenible, romperán su "bonito" diseño denso, conciso y SECO mientras maldice su nombre. No hagas esto He sido esa persona y cada vez que veo un nombre determinado en la anotación del código, me estremezco.

Es inteligente hacer un código denso que carezca de "variables descriptivas" y pegar todo en expresiones ternarias anidadas con lambdas sin ningún tipo de documentación. Es bueno saber que puedes hacerlo, pero no lo hagas. El código inteligente es muy difícil de depurar. Evite escribir código inteligente .

La mayor parte del tiempo empleado en el software se emplea en el mantenimiento del software, no en escribirlo por primera vez. Escriba el código para que usted (o alguien más) pueda corregir los errores de manera rápida y fácil y agregar las funciones según sea necesario, con la menor cantidad de cambios de diseño ideal.

    
respondido por el user40980 10.04.2013 - 04:25
fuente
17

No estoy seguro basado en la pregunta que entiendes SECA. El código DRY no es lo mismo que conciso. Muy a menudo es lo contrario.

Aquí, no estoy seguro de cuál es el problema para este ejemplo. Cree una función para cifrar, una función para descifrar, ayudantes para la funcionalidad común (mezcla de bytes) y un front-end simple para tomar información y determinar cifrar / descifrar ... No se repita.

En general, sin embargo, tanto DRY como legibilidad existen para ayudar a mantener y extender el código. No todos los escenarios son iguales, un gran golpe de legibilidad para eliminar una pequeña repetición no es bueno, y tampoco es un montón de duplicación para agregar un poco de legibilidad.

Si se presiona, preferiría la legibilidad. El código duplicado aún puede ser probado; un código ilegible lo lleva a hacer (y probar) algo incorrecto.

    
respondido por el Telastyn 10.04.2013 - 04:24
fuente
11

No estoy familiarizado con su caso específico, pero puedo dar algunas pautas generales.

El propósito de legibilidad y DRY es mantenibilidad .

La capacidad de mantenimiento es importante en la mayoría de las situaciones, dedicará más tiempo a mantener el código que a escribirlo. Esto es especialmente cierto si considera que escribir código es un tipo especial de mantenimiento.

Desafortunadamente, DRY es a menudo mal entendido. Esto es en parte porque parece muy simple, pero como muchas cosas simples puede ser, bien ... complicado.

La intención de DRY es que cada unidad de funcionalidad exista en un solo lugar. Si se sigue el principio, el mantenedor del código que tiene la tarea de cambiar o verificar que la funcionalidad puede manejar el código una vez. Si no se sigue DRY, existe el peligro real de que alguna copia de la funcionalidad no se mantenga correctamente.

La violación más flagrante de DRY es la codificación de copiar y pegar, donde se repiten verbatum bloques enteros de código en la base del código. Esto es sorprendentemente común en mi experiencia, y de ninguna manera eso contribuye a mejorar la legibilidad. Por lo tanto, refactorizar el código para introducir un método común aumenta invariablemente la conformidad y la legibilidad DRY.

La segunda violación más flagrante es "copiar y pegar y cambiarla un poco". Una vez más, refactorizar para introducir un método común con parámetros, o dividir una función en pasos y abstraer los puntos en común casi siempre aumenta la legibilidad.

Luego están las violaciones más sutiles, donde la funcionalidad se duplica pero el código es diferente. Esto no siempre es fácil de detectar, pero cuando lo ves y refaccionas el código común en un solo método / clase / función, entonces el código es usualmente más legible que antes.

Finalmente, están los casos de repetición de diseño. Por ejemplo, podría haber usado el patrón de estado varias veces en su base de código, y está considerando la refactorización para eliminar esta repetición. En este caso, proceda con precaución. Es posible que esté reduciendo la legibilidad al introducir más niveles de abstracción. Al mismo tiempo, en realidad no se trata de la duplicación de la funcionalidad sino de la abstracción. A veces vale la pena ... pero a menudo no lo es. Su principio rector será preguntar, "cuál de estos es más fácil de mantener".

Cuando hago estas llamadas de juicio, trato de considerar la cantidad de tiempo que las personas pasarán manteniendo el código. Si el código es la funcionalidad principal del negocio, probablemente necesitará más mantenimiento. En esos casos mi objetivo es hacer que el código sea mantenible para las personas que están familiarizadas con el código base y las abstracciones involucradas. Estaría más feliz de introducir un poco más de abstracción para reducir la repetición. En contraste, una secuencia de comandos que rara vez se usa y se mantiene con poca frecuencia podría ser menos fácil de entender para los mantenedores si implica demasiada abstracción. En ese caso me equivocaría en el lado de la repetición.

También considero el nivel de experiencia de otros miembros de mi equipo. Evito las abstracciones "sofisticadas" con desarrolladores sin experiencia, pero aprovecho los patrones de diseño reconocidos en la industria con grupos más maduros.

En conclusión, la respuesta a su pregunta es hacer lo que haga que su código sea más fácil de mantener. Lo que eso significa en su situación depende de usted para decidir.

    
respondido por el Kramii 10.04.2013 - 08:52
fuente
7

Si tus funciones se vuelven más complicadas y más largas (por lo tanto, menos legibles) cuando intentas que sean SECAS, lo estás haciendo mal. Está intentando poner demasiada funcionalidad en una función porque piensa que esta es la única forma de evitar repetir las mismas piezas de código en una segunda función.

Hacer que el código sea DRY es casi siempre refactorizar la funcionalidad común a funciones más pequeñas. Cada una de esas funciones debe ser más simple (y, por lo tanto, más legible) que la original. Para mantener todo en la función original en el mismo nivel de abstracción, esto también puede significar refactorizar partes adicionales que no se utilizan en otros lugares. Entonces, su función original se convierte en una "función de alto nivel", al llamar a las más pequeñas, y también se vuelve más pequeña y más simple.

Por lo tanto, hacer esto conduce principalmente a diferentes niveles de abstracciones en su código, y algunas personas creen que este tipo de código es menos legible. Para mi experiencia, esto es una falacia. El punto clave aquí es dar buenos nombres a las funciones más pequeñas, introducir tipos de datos y abstracciones bien nombrados que puedan ser fácilmente comprendidos por una segunda persona. De esa manera, "DRY" y "legibilidad" solo deberían entrar en conflicto muy, muy raramente.

    
respondido por el Doc Brown 10.04.2013 - 08:53
fuente
2

Si bien no estoy seguro de qué es exactamente lo que está causando el problema, mi experiencia es que cuando encuentras DRY y la legibilidad en conflicto, dice que es hora de refactorizar algo.

    
respondido por el Loren Pechtel 10.04.2013 - 05:33
fuente
0

Elegiría legible (= mantenible) en lugar de SECO cualquier día de la semana. En realidad, ambos se alinean a menudo, alguien que percibe el concepto de DRY generalmente produce (en su mayoría) código legible.

    
respondido por el Zdravko Danev 10.04.2013 - 04:23
fuente
0

Muy, muy, muy, muy pocas veces en mi carrera, he encontrado un caso legítimo que se opone a la legibilidad contra DRY. Hazlo legible primero. Nombra bien las cosas. Copiar y pegar si es necesario.

Ahora retroceda y observe la totalidad que ha creado, como un artista que retrocede para mirar su pintura. Ahora puedes identificar correctamente la repetición.

El código repetido se debe refactorizar en su propio método o en su propia clase.

Repetir código debería ser un último recurso. Legible Y SECO primero, fallando así de legible si limita el alcance del código repetido.

    
respondido por el Greg Burghardt 10.03.2017 - 00:10
fuente

Lea otras preguntas en las etiquetas