A veces, un algoritmo se puede escribir de dos maneras:
- El camino corto y elegante; o
- La forma más larga y fácil de entender.
Por ejemplo, aquí es un camino más largo, más fácil de copiar una cadena source
que dest
en C:
*dest = *source;
while (*source != '\0') {
source++;
dest++;
*dest = *source;
} (true);
Y aquí hay una forma corta y elegante.
// Copy string source to dest
while (*dest++ = *source++);
Siempre he escuchado y leído que se debe evitar el código elegante, y tiendo a estar de acuerdo. Pero, ¿qué pasa si tomamos en cuenta los comentarios? Supongamos que, como en los ejemplos anteriores, tenemos un código no comentado, más largo y supuestamente más fácil de entender, y un código bien comentado, corto y elegante. ¿Todavía se prefiere el código no elegante?
EDITAR: Muchos han comentado los nombres de las variables, por lo que he modificado el código de ejemplo para que no sea un factor al preferir sobre el otro. Traté de eliminar la doble asignación en el primer ejemplo, pero eso solo hizo que el código fuera menos legible.
Quizás este no fue el mejor ejemplo porque muchos encuentran que el código 'elegante' es más legible y comprensible que el código más largo. La idea era tener un código más largo que fuera mucho más fácil de entender que un código muy corto pero complicado.
EDIT2: Aquí hay un nuevo examen que obtuve de SO :
Versión de lujo comentada:
//direct formula for xoring all numbers from 1 to N
int Sum = (N & (N % 2 ? 0 : ~0) | ( ((N & 2)>>1) ^ (N & 1) ) );
Versión larga no comentada:
int Sum = 0;
for (int i = 1; i < N; ++i)
{
Sum ^= i; //or Sum = Sum ^ i;
}
Respuestas:
Generalmente preferiría extraer el código elegante en su propio método.
En lugar de comentar el código elegante, el nombre del método debería ser todo lo que necesita para aclarar las cosas.
fuente
Estoy a favor de la versión más larga. El problema con la versión corta del código, además de que es más difícil de leer para algunos programadores, es que la mayoría de las veces es más difícil detectar errores con solo mirarlo.
Tengo un ejemplo de la vida real. En nuestro producto teníamos el siguiente fragmento de código:
Este código parece perfectamente razonable a primera vista, pero después de un largo período de tiempo, este contador se desborda y rompe la condición (en el escenario de la vida real aplastamos el sistema de producción de nuestro cliente con un OOM). Este código es un poco menos "sofisticado", pero está claro que hace lo que se supone que debe hacer:
Y puede decir que el desarrollador que escribió este código simplemente no era lo suficientemente bueno (lo cual no es cierto, era un tipo bastante brillante), pero creo que si su técnica de codificación requiere que sea un experto en programación GOD Para obtener su código correcto, está haciendo algo mal. Su código debe ser tan infalible como sea posible por su bien y por quien tenga que mantener este código después de usted (que puede no ser tan inteligente como usted).
Entonces, estoy a favor de la simplicidad y la claridad.
Editar: Ah, y con respecto a los comentarios, no importa. Muchas personas no leerán comentarios de todos modos ( http://www.javaspecialists.co.za/archive/Issue039.html ) y aquellos que no entiendan su código sin comentarios, no lo entenderán lo suficientemente bien con ellos para que puedan puede mantenerlo El objetivo es ayudar a las personas a ver que cierto código es "correcto", los comentarios no pueden ayudar con eso.
fuente
Generalmente preferiría la versión más larga. Se me ocurren dos razones principales:
Para lo mejor de ambos mundos, envuelva el código en una función, cuyo nombre hace el comentario por usted:
La única razón para no hacer esto sería si el rendimiento fuera un problema y la elaboración de perfiles realmente demostrara que la sobrecarga de la función es significativa.
fuente
Lo que sea más claro. A menudo es un fragmento de código compacto y fácil de entender que no requiere un comentario ... como su segundo ejemplo.
Por lo general, los fragmentos de código más cortos son más fáciles de entender, ya que hay menos para que el lector tenga en mente a la vez. Obviamente, hay un límite cuando el código se ofusca demasiado y no quiero decir que se deba recortar el espacio en blanco que mejora la claridad.
Los comentarios nunca deben indicar algo obvio del código, que solo haga que el lector lea lo mismo dos veces. Para mí, el primer fragmento requiere una aclaración. ¿Por qué el desarrollador no ha utilizado un
do...while
bucle para eliminar los duplicados de la*s = *t;
tarea? Tengo que analizar más código para darme cuenta de que está implementando una copia de cadena. Un comentario sería más útil en este código más largo que en el código más corto.El comentario sobre el segundo fragmento es casi redundante, ya que el bucle while es prácticamente idiomático, pero dice lo que hace el código en un nivel superior al código en sí mismo, lo que lo convierte en un comentario útil.
fuente
do ... while
simplemente porque no lo pensé cuando escribí la pregunta. Gracias por señalar eso. ^^ El segundo fragmento puede ser obvio para usted, pero ciertamente no lo es para mí.El problema es que no hay una definición clara
short fancy code
ya que depende mucho del nivel del programador. Mientras que algunas personas no tienen problemas para comprender unawhile(*s++ = *t++);
expresión, otras sí.Personalmente, encuentro el más
while(*s++ = *t++);
legible y el más largo más difícil de leer. Sin embargo, otros podrían no estar de acuerdo.De todos modos, es solo una cuestión de usar el sentido común. La legibilidad definitivamente debería ser una prioridad, pero hay un punto en el que el código más largo se vuelve menos legible cuando se hace más largo. La verbosidad a menudo reduce la legibilidad de mi experiencia.
fuente
Tengo que estar en desacuerdo con la mayoría de las otras respuestas aquí: creo que (al menos en este caso) el código más corto es mejor. Contrariamente a su reclamo, el código más largo no es "más fácil", al menos para un lector. En todo caso, parece que ha dejado de querer alargarlo, a pesar de que hace que el código sea más difícil de entender y / o tenga la seguridad de un funcionamiento correcto.
En particular, tener la asignación del primer byte de la cadena fuera del bucle, separada de la asignación para los otros bytes, significa que uno debe tener mucho más cuidado al leer para asegurarse de que todos los bytes se copien correctamente. La secuencia básica de acciones en la versión más corta es mucho más fácil de verificar. Su único problema real está en el formato: cuando tiene un cuerpo de bucle intencionalmente vacío, es mejor dejarlo claro, algo como:
o incluso:
Algunas personas prefieren usar llaves en su lugar:
Independientemente del formato exacto que prefiera, se han cometido suficientes errores con cosas como:
... que es importante asegurarse de que 1) es obvio lo que está realmente controlado por cualquier control de flujo, y 2) es obvio que el código fue escrito sabiendo lo que estaba controlado por él, para que alguien que lo lea no pierda el tiempo intentando para averiguar si acaban de encontrar un error.
fuente
Asegúrese de que cualquier otro programador pueda entender lo que hace su código, y aún mejor si es de un vistazo (aquí es donde los buenos nombres y comentarios entran en juego).
El sofisticado ensamblaje en línea y el kung-fu de bit-twiddling es genial en nombre de la optimización (quizás innecesaria y prematura), pero cuando ni siquiera puedes entender el código que escribiste cuando te encuentras con un error dos meses después ... ¿Cuál era el punto? Te costarás tiempo y esfuerzo.
A menudo me refiero al Zen de Python en estas situaciones. En particular:
fuente
No escriba código sofisticado en software de producción. Sé que se siente bien poder escribir eso, y es más corto. Escribir código sofisticado aumenta significativamente el valor "WTF / minuto", en otras palabras, disminuye la calidad.
fuente
Por supuesto, depende completamente de las circunstancias. pero en general, considero que esta es una buena regla general:
~ Brian Kernighan
fuente
En mi experiencia, la mayor victoria en términos de código corto y elegante tiende a ser recurrente en lugar de iteración. También es una de las cosas más difíciles de entender al revisar el código, a menos que esté trabajando en el tipo de lenguaje donde todo es recursivo de todos modos. Todavía lo favorecería por la elegancia y la velocidad de desarrollo que ofrece, pero trato de asegurarme de que tenga comentarios detallados si parece que será opaco para los futuros mantenedores o para mí mismo.
fuente
Estoy empezando a no confiar nunca en los comentarios. Con demasiada frecuencia, los comentarios no se actualizan cuando se actualiza el código y están muy desactualizados o representan reglas de clientes / administradores que ya no son relevantes.
Ha llegado al punto en algunos casos donde los comentarios ya ni siquiera coinciden con el código que están describiendo.
Si tengo que elegir entre corto / elegante y más largo / más fácil de entender, siempre elijo este último a menos que haya realmente buena razón.
fuente
La legibilidad y la facilidad de mantenimiento son clave, y su segundo ejemplo (es decir, el más largo) es mucho más de ambos. Pero, ¿por qué limitarse a dos opciones? Incluso el código más largo es demasiado complejo (en mi humilde opinión) para no anotar más. Lo pondría en un método propio con Javadoc apropiado (o lo que sea) y un nombre de método adecuado.
fuente