¿Cómo define el código elegante? [duplicar]

70

En una discusión sobre la calidad de la codificación, y cómo la identificas, encontré una discusión sobre cómo probar la capacidad de codificación de las personas al mostrarles cómo intercambiarían dos valores utilizando una pieza de código para lograr el objetivo. Se produjeron dos soluciones clave:

  1. Introduzca una variable de repuesto para hacer que algunos pasen la parcela de los valores o:
  2. Use algunos operadores bitwise.

Luego surgió un argumento sobre cuál era, de hecho, la mejor solución (me inclinaría por la primera opción al ser consciente de que existe la segunda, pero es posible que no siempre se evalúe según lo esperado según los valores en cuestión).

Teniendo en cuenta la historia de Mel the Real Programmer , me interesa conocer la forma en que evalúa el código como elegante o no, y es una característica clave de un código elegante.

    
pregunta temptar 12.04.2017 - 09:31

22 respuestas

76

El buen código debe ser limpio, simple y fácil de entender en primer lugar. Cuanto más simple y limpio es, menor es la posibilidad de que los insectos se deslicen. Como lo acuñó Saint-Exupery, "La perfección se logra, no cuando no hay nada más que agregar, sino cuando no hay nada más que quitar".

Además, el código elegante suele ser el resultado de un análisis cuidadoso del problema, y de encontrar un algoritmo y un diseño que simplifique el código en gran medida (y que a menudo lo acelere también). P.ej. Programming Pearls muestra varios ejemplos en los que una visión obtenida durante el análisis dio un ángulo totalmente diferente a Ataque, resultando en una solución muy simple, elegante y corta.

Mostrar lo inteligente que es el autor, solo viene después de estos ;-) La microoptimización del rendimiento (como el uso de las operaciones a nivel de bits que usted menciona) se debe usar solo cuando se puede probar (con medidas concretas) que la pieza de código en cuestión es el cuello de botella, y que el cambio realmente mejora el rendimiento (he visto ejemplos en contrario).

    
respondido por el Péter Török 03.08.2011 - 16:03
47

El código elegante es una combinación de:

  • corrección. En mi humilde opinión, ningún código incorrecto puede ser realmente elegante.
  • sucintidad. Menos código significa menos equivocarse, menos comprender *.
  • legibilidad. Cuanto más fácil sea entender el código, más fácil de mantener.
  • Rendimiento. A un punto. El código prematuramente pesimista no puede ser realmente elegante.
  • Siguiendo los estándares establecidos de la plataforma o proyecto. Cuando se presentan dos opciones igualmente elegantes, la que está más cerca del estándar establecido es la mejor.
  • Exactamente de la manera que lo haría. Bien, estoy bromeando, pero es fácil etiquetar el código que NO es como lo harías como "inelegante". Por favor, no hagas eso: mantén la mente abierta a un código diferente.

Por supuesto, también está el adagio real muy a menudo: "Para cada problema hay una solución que es simple, elegante e incorrecta".

* Como se muestra en los comentarios a continuación, hay algo de contención en el código más corto. "Sucinto" no significa "en el menor número de caracteres posible", significa "Expresado de manera breve y clara".

    
respondido por el MadKeithV 03.08.2011 - 16:31
28

El código simple es un código tan legible que incluso los programadores novatos pueden averiguar (al menos en general) qué está haciendo el código. (Consulte: sintaxis de expresión de Ruby )

El código impresionantemente complejo es un código que hace todo lo posible en el menor número de líneas posible, sin tener en cuenta la legibilidad (ver: Perl )

Código elegante es un código que hace que otros desarrolladores digan "¡Oh, hombre, ¿por qué no pensé en eso?" Es una especie de entre los dos primeros, con un código que puede no ser tan evidente que tus padres pueden leerlo, pero no un garabato arcano que requiere un códice para interpretar. Hace el trabajo, lo hace bien y no deja que las personas mantengan el código rascándose la cabeza.

    
respondido por el asfallows 02.08.2011 - 16:46
13

Fred Brooks divide la complejidad de una solución en las categorías de "complejidad esencial" y "complejidad accidental" . El código perfectamente elegante, para mí, es el que es todos "complejidad esencial", y no "complejidad accidental". El truco es que los diferentes programadores tendrán diferentes ideas sobre lo que es "complejo", por lo que es probable que no estemos de acuerdo sobre si un poco de código es elegante.

Por ejemplo, encuentro que la estructura del código Lisp es significativamente más elegante que la estructura del código en lenguajes tipo C. Por otro lado, la notación de prefijo de Lisp y la construcción explícita de árbol de análisis violan nuestra intuición acerca de cómo deben ser las expresiones matemáticas, lo que puede dificultar la lectura del código lisp para las personas. Como resultado, muchos programadores consideran que todos esos paréntesis en Lisp no son "elegantes" en absoluto, sino que de hecho son bastante feos. Para alguien que está realmente preocupado por cómo el compilador interpretará el código, Lisp puede parecer elegante. Para alguien que está más preocupado por cómo las personas interpretarán el código, Lisp puede parecer feo.

    
respondido por el Aidan Cully 02.08.2011 - 18:04
11

La sucintidad es un componente importante, pero para mí, para llamarme elegante, el código también debe ser fácilmente comprensible hasta el punto que dice: "¡Por supuesto que es la forma más obvia de hacerlo!" Incluso si, paradójicamente, no es la primera forma en que pensaste. Si no pasa esa prueba, puede llamarse "inteligente" o "eficiente", pero no elegante.

    
respondido por el Karl Bielefeldt 02.08.2011 - 15:42
10

Es similar a la poesía, que es un lenguaje elegante.

Los poetas pueden decir en muy pocas palabras lo que les tomaría a otras páginas, y páginas, decir y no tan bien. Los codificadores elegantes pueden hacer lo mismo con el código.

Un ejemplo típico es comparar una implementación típica de quicksort en C con quicksort en Haskell:

quicksort :: Ord a => [a] -> [a]
quicksort []     = []
quicksort (p:xs) = (quicksort lesser) ++ [p] ++ (quicksort greater)
    where
        lesser  = filter (< p) xs
        greater = filter (>= p) 

(menor y mayor puede estar en línea para una solución de tres líneas).

    
respondido por el 3 revs, 2 users 82%user1249 03.08.2011 - 15:54
7

El swap XOR es bastante conocido. Y todo el mundo, que tiene al menos un poco de la humildad que pidió Dijkstra, le dirá que es la forma incorrecta de hacer las cosas. No solo es más difícil de leer para los humanos, sino también para los compiladores. Los compiladores son relativamente buenos en el análisis de flujo y la asignación de registros y todo tipo de cosas. No puede esperar que tenga un buen compilador, que cada variable que cree realmente existirá en la pila / en un registro en cualquier momento. Lo que hay que hacer es expresar las cosas con claridad. En un idioma que admite la llamada por referencia, esta es la forma de ir: swap(x, y); .
Esta es la mejor solución (me atrevo a decir que sí, al menos dadas las alternativas que proporcionó). Es una declaración de una y se explica por sí misma. No usa vudú como lo hace el intercambio XOR. No introduce el ruido de una variable temporal y 3 declaraciones de asignación. Eso es algo que sucede dentro del intercambio. Suponiendo que es una función, un compilador decente integrará esta llamada. También podrías hacer una macro. Lo que sea.

Lo que hace que el código sea realmente elegante es la falta de redundancias, la ortogonalidad, la simplicidad. Asegura sistemas robustos que crecen unos sobre otros. Tener grupos de instrucciones recurrentes por todas partes en cualquier momento que desee un intercambio introduce redundancia, carece de ortogonalidad y falla en la simplicidad.

    
respondido por el back2dos 03.08.2011 - 16:00
4

Es fácil detectar lo que hace el código elegante. Obtienes el "¿Por qué no pensé en eso?" ambiente. Esto en relación con la complejidad del problema y el lenguaje que se utiliza.

Esto no significa que la solución mejor o más simple sea automáticamente elegante. Simple es a menudo una de sus cualidades. Las modificaciones, aunque generalmente son más fáciles, no siempre mantienen el equilibrio.

    
respondido por el JeffO 02.08.2011 - 16:57
2

Lo bueno es la ausencia de lo malo. Se aplica a todo en la vida y el código no es una excepción. Por lo tanto,

  

¡El código bueno es aquel que no tiene olor! Por lo tanto, es importante que usted vea y comprenda qué es el olor de un código. No hay broma prevista.

Piénsalo. Dices que eres feliz solo porque NO estás triste o te has librado de tu tristeza. Del mismo modo, usted llama a algo un buen código, cuando no ve nada malo en el código. Cada aspecto de calidad del código (capacidad de mantenimiento, legibilidad, etc.) puede lograrse eliminando el olor del código. Y lo creas o no, esto no sucede la primera vez, sucede de manera iterativa :)

    
respondido por el karthiks 02.08.2011 - 19:52
2

Me gusta comparar el código con los medios impresos aquí.

Sabes que lo odias cuando lees artículos simplificados. Callados. Pocos hechos, oraciones simples. Esto se traduce en el código que vinculo a los principiantes: trivial, ingenuo incluso, implementación, nada es demasiado complicado, pero es largo y lleno de pasos innecesarios.

Por otro lado, conoces este estilo de torre de marfil. Lees un libro de filósofos conocidos. Lees un artículo de ciencia sobre un asunto complicado: el estilo a menudo parece ser muy largo. Las palabras no se reutilizan, debes mostrar que puedes conocer una docena de sinónimos. Si bien el contenido real puede ser puro, bueno, interesante, el estilo de escritura hace que sea difícil de seguir. Este estilo desdibuja la línea original de pensamientos. Este es el código inteligente .

El código elegante se encuentra en el medio y es tan subjetivo como lo pueden ser las preferencias. Puede detectar y describir los casos graves fácilmente, pero la perfección es diferente para la mayoría de nosotros.

    
respondido por el Benjamin Podszun 03.08.2011 - 16:13
2

La elegancia es la minimización de la complejidad. Si puede pasar rápidamente el código a otro programador con habilidades razonables y ellos pueden continuar el trabajo (y es de esperar que cumplan con su estándar inicial), es probable que el código sea elegante.

El software bien escrito debe permanecer durante al menos diez años. La elegancia inicial puede asustarse por los ataques posteriores, pero la cantidad de tiempo que el código sobrevive es a menudo una medida razonable de lo bien que se escribió inicialmente. El código mal escrito o bien se estanca (y las personas lo piratean) o se vuelve a trabajar (aunque en la práctica he visto personas que reemplazan el código elegante por soluciones menores porque no lo vieron con cuidado).

    
respondido por el Paul W Homer 03.08.2011 - 18:34
1

Mi definición es simple, desafortunadamente, no puedes determinar (todo) tú mismo.

Código elegante tiene las siguientes características:

  • Resuelve el problema.
  • Puedo confiar en las pruebas, de modo que si modifico cualquier comportamiento, se romperá una prueba.
  • Cuando I o + cualquier otro desarrollador + abre el código, es inmediatamente fácil de seguir. Cualquier bloque lógico no trivial se describe mediante un comentario.
  • Las cosas simples son simples, las cosas difíciles son posibles.
  • Alguien más está + dispuesto + a asumir el desarrollo del código a pesar de que todavía estoy allí. Sin ser forzado.
respondido por el Dmitriy Likhten 03.08.2011 - 18:21
0

¿Con qué facilidad pueden leerlo la mayoría de los desarrolladores? ¿Qué tan fácil es cambiar?

Como resultado, estoy totalmente de acuerdo con usted en que Opton 1 es significativamente más elegante.

La opción 2 es inteligente y muestra un buen conocimiento de los operadores. También guarda un pedazo de memoria muy pequeño. Tal vez sea útil en casos excepcionales, y vale la pena que un desarrollador pueda hacerlo. Pero no en tu caso promedio del 99%.

    
respondido por el pdr 02.08.2011 - 15:43
0

Tenía que ser consistente . Tenía que haber algún tipo de patrón en él. Y cuando necesite romper ese patrón, divídalo de manera consistente, de modo que en general todavía haya algún tipo de patrón.

Si alguien señala tu código y te pregunta por qué lo haces de esta manera, y tu respuesta es "No lo sé, lo estoy haciendo de esta manera porque así me enseñaron / porque así es como todos los demás están haciendo ", entonces ese código puede ser elegante o no elegante . Sin embargo, si puede explicar por qué el código es así, por qué eligió codificarlo de esa manera, por qué las otras alternativas no son tan atractivas, entonces puede estar seguro de que el código es elegante .

    
respondido por el Pacerier 02.08.2011 - 16:01
0

Fui blasé en mi comentario en la parte superior, pero para mí el código elegante es el que afecta a mis sentidos mucho más que a la mayoría.

Produce una reacción positiva para lograr objetivos al mismo tiempo que es breve y simple, simpleza pero con propósito y potencia, elegante, simétrico y un poco 'fuera de la caja'. Incurre en un elemento de sorpresa. El método y el algoritmo no son tan complejos (al menos superficialmente) como para interferir en su comprensión.

El código elegante es más que la suma de sus partes. A veces, el código elegante parece casi funcionar con los datos, doblarse con ellos, en lugar de usar la fuerza bruta o mapear los datos en otra forma. Para mí, la elegancia a menudo viene en un paquete independiente: una sola función, pocas o ninguna llamada externa, ni demasiado larga ni demasiado corta.

Por ejemplo, he visto métodos de clasificación que llamaría elegantes. ¡Y código / algoritmos elegantes para dibujar fractales de formas inusuales pero altamente eficientes, combinando la belleza visual y codificando la elegancia!

    
respondido por el Roger Attrill 02.08.2011 - 16:45
0

El código elegante usa la inteligencia para lograr algo en mucho menos código de lo que la mayoría de las personas pensaría posible, pero de una manera que es legible y obvia en retrospectiva y no se parece al código de golf.

    
respondido por el dsimcha 02.08.2011 - 17:01
0

Personalmente encuentro que el código elegante está sobrevalorado. Pero trabajo en el mundo de la base de datos donde el código de rendimiento es de importancia crítica y el código "elegante" en el contexto del código SQL con mayor frecuencia (al menos en mi experiencia) no funciona bien. Me estremezco cada vez que escucho a alguien que quiere escribir código SQL elegante.

Sin embargo, en general, sigo pensando que luchar por la elegancia es ridículo. En primer lugar, nadie puede definirlo correctamente. Lo que desea es un código que funcione correctamente, que funcione bien, que se pueda mantener y que elegante sea un cuarto muy lejano, incluso si está en la lista.

    
respondido por el HLGEM 02.08.2011 - 20:22
0

El código elegante no es lo mismo que el diseño elegante, aunque hay un cruce entre los dos.

¿Cómo se define una pintura elegante? Es hermoso de ver, perfectamente legible, tiene mucho sentido, es fácil de mantener y simplemente hace el trabajo.

El diseño elegante ayuda en el código elegante. No puedes tener un código elegante sin un buen diseño, pero puedes tener un código feo con un buen diseño. Mucho mejor escribir si can_can_add_apples_to_my_basket (20) entonces   add_apples_to_basket (20) más  render_not_enough_room_to_add_apples (20) fin luego escriba el 2 si las condiciones serían potencialmente reutilizables donde las necesite para lo que las necesite (ese es el bit de diseño)

código

que dice si b.count + 20 < = b.max entonces   b + = 20 más   elevar ("demasiadas manzanas") fin

Todavía tiene los 2 métodos (contar y máximo), por lo que aún tiene un buen diseño, pero el código es feo y sin sentido, es difícil de mantener sin el conocimiento del sistema y es totalmente ambiguo

    
respondido por el jamesc 03.08.2011 - 06:00
0

Para ser honesto, rara vez hay una buena razón para intercambiar el valor de dos variables, y no es realmente una cosa "elegante", no importa cómo lo hagas.

El código elegante no se trata del código en sí mismo, se trata realmente de lo que hace el código y cómo lo hace. Personalmente creo que este es un mal ejemplo para determinar qué es el "código elegante", ya que lo que se está haciendo no es elegante en sí mismo. Encuentro que el código de Haskell es típicamente elegante, porque (en su mayor parte) trata con valores inmutables . Sin embargo, los algoritmos que utilizan el estado mutable también pueden escribirse con elegancia (y, por lo general, no se ven muy bien en Haskell).

    
respondido por el Dan Burton 03.08.2011 - 09:56
0

Realmente depende de a quién le preguntes. Alguien que viene de una formación matemática a menudo preferirá el código que un programador experimentado puede encontrar problemático. Esto lo hace parecer muy subjetivo.

Además, encontrará que los diferentes idiomas tienen diferentes maneras de resolver el mismo problema. En Python, por ejemplo, intercambiar dos variables es trivial: x, y = y, x

En la práctica, la mayoría de los programadores estarían de acuerdo en que hay algunos criterios comunes:

  • el código elegante debe ser lo más corto posible
  • pero tan detallado como sea necesario
  • debería ser fácil de seguir
  • cada declaración debe ser fácil de entender
  • ninguna declaración debe parecer redundante o superflua
  • el código debe seguir las expresiones idiomáticas del idioma
  • no debe hacer uso de abstracciones con fugas

Esta es una visión muy pragmática de la elegancia. El código no debe ser "inteligente" o no cumple estos criterios. Pero será mantenible y más fácil de ajustar y extender.

Dicho esto, hay un código que puede ser una obra de arte a pesar de fallar absolutamente por la mayoría de las reglas en esta lista. El código "inteligente" a menudo cae en esta categoría. Es muy denso, a menudo se basa en una comprensión profunda de las implementaciones subyacentes (por ejemplo, la gestión de la memoria o la implementación exacta del compilador), pero sin embargo evoca una fascinación sublime.

Hay una diferencia entre la elegancia que encontraría en los scripts de Yet Another Perl Hacker contra el código que realmente desearía usar en producción. Esta es la razón por la que nunca querrías que Mel estuviera en tu equipo, a pesar de que podrías llamar elegante a su mayor obra.

    
respondido por el Alan Plum 03.08.2011 - 15:33
0

Comprender el código elegante debería ser como resolver un rompecabezas. Debería ser difícil de entender al principio, y luego muy fácil de entender una vez que lo tiene "entendido".

Hay una compensación: las personas que no lo entienden se quedan rascándose la cabeza, mientras que las personas que sí lo entienden lo consideran obvio, en retrospectiva.

En cuanto a las variables de intercambio, ninguna será particularmente elegante. No hay que dominar la complejidad aquí, por lo que no hay espacio para una solución "elegante".

    
respondido por el wisty 03.08.2011 - 17:39
-2
isElegant(code)
{
  return isSimple(code) && isReadable(code) && code.reducesComplexity();
}
    
respondido por el zzzzBov 02.08.2011 - 20:37

Lea otras preguntas en las etiquetas