¿Cómo se mantienen las enormes bibliotecas de código abierto mientras se mantiene el código lejos de las prácticas de "código limpio"?

78

Todavía no tengo experiencia en escribir código de alta calidad, así que leo libros que abordan el tema como Clean Code de Robert C. Martin, y continúo revisando el código de bibliotecas conocidas para mejorar mi habilidades.

Aunque muchas bibliotecas de código abierto se han mantenido durante años, lo que significa que es muy poco probable que no estén en el camino correcto, encontré que el código de muchos de ellos está muy lejos de los principios a los que se dirige para escribir código limpio: por ejemplo, métodos que contienen cientos de líneas de código.

Entonces, mi pregunta es: ¿Están los principios de código limpio demasiado restringidos, y podemos prescindir de ellos en muchas bibliotecas como estas? Si no es así, ¿cómo se mantienen las enormes bibliotecas sin tener en cuenta muchos de estos principios?

Apreciaré cualquier breve aclaración. Pido disculpas si la pregunta parece ser tonta de un chico novato.

EDIT

Marque esto ejemplo en la biblioteca Butterknife - una de las bibliotecas más conocidas de la comunidad de Android.

    
pregunta Islam Salah 11.07.2018 - 12:25

9 respuestas

83

Buena respuesta aquí ya, pero déjame decirte una palabra acerca de tu butterknife : aunque no tengo idea de lo que hace el código, a primera vista, no me parece que sea realmente imposible. Las variables y los nombres de los métodos parecen elegirse deliberadamente, el código está correctamente sangrado y formateado, tiene algunos comentarios y los métodos largos al menos muestran cierta estructura de bloques.

Sí, de ninguna manera sigue las reglas de "código limpio" del Tío Bob, y algunos de los métodos son demasiado largos (probablemente toda la clase). Pero mirando el código, todavía veo suficiente estructura para que puedan "limpiarse" fácilmente extrayendo esos bloques en métodos por su cuenta (con un bajo riesgo de introducir errores al usar herramientas de refactorización).

El problema real con este código es, agregar un bloque y otro bloque y otro bloque funciona en cierta medida, a veces durante años. Pero cada día el código se vuelve más difícil de evolucionar un poco, y demora un poco más en modificarlo y probarlo. Y cuando realmente tienes que cambiar algo que no se puede resolver "agregando otro bloque", pero requiere una reestructuración, desearás que alguien haya comenzado a limpiar el código más pronto.

    
respondido por el Doc Brown 11.07.2018 - 16:26
157

Los principios establecidos en el "Código de limpieza" no siempre se acuerdan generalmente. La mayor parte es de sentido común, pero algunas de las opiniones del autor son bastante controvertidas y no son compartidas por todos.

En particular, la preferencia por métodos cortos no es acordada por todos. Si el código en un método más largo no se repite en otra parte, extraer parte de él en un método separado (para obtener múltiples métodos más cortos) aumenta la complejidad general, ya que estos métodos ahora son visibles para otros métodos que no deberían preocuparse por ellos. Así que es una compensación, no una mejora objetiva.

El consejo en el libro también está (como todos los consejos) orientado hacia un tipo particular de software: aplicaciones empresariales. Otros tipos de software, como los juegos o los sistemas operativos, tienen diferentes restricciones que el software de la empresa, por lo que están en juego diferentes patrones y principios de diseño.

El lenguaje también es un factor: Clean Code asume Java o un lenguaje similar. Si usas C o Lisp, muchos de los consejos no se aplican.

En resumen, el libro es una opinión de personas individuales sobre una clase particular de software. No se aplicará en todas partes.

En cuanto a los proyectos de código abierto, la calidad del código varía de abismal a brillante. Después de todo, cualquiera puede publicar su código como código abierto. Pero si observa un proyecto de código abierto maduro y exitoso con múltiples colaboradores, puede estar bastante seguro de que se han establecido conscientemente en un estilo que les funcione. Si este estilo está en contradicción con alguna opinión o directriz, entonces (para decirlo sin rodeos) es la directriz que es incorrecta o irrelevante, ya que el código de trabajo triunfa sobre las opiniones.

    
respondido por el JacquesB 11.07.2018 - 13:35
33

Summary

Como escribe JacquesB, no todos están de acuerdo con el "Código Limpio" de Robert C. Martin.

Los proyectos de código abierto que encontró que estaban "violando" los principios que esperaba probablemente tengan otros principios.

Mi perspectiva

Resulta que superviso varias bases de código que se adhieren mucho a los principios de Robert C. Martin. Sin embargo, realmente no afirmo que estén bien , solo puedo decir que funcionan bien para nosotros , y que "nosotros" es de hecho una combinación de al menos

  • el alcance y la arquitectura de nuestros productos,
  • las expectativas del mercado objetivo / cliente,
  • cuánto tiempo se mantienen los productos,
  • la metodología de desarrollo que utilizamos,
  • la estructura organizativa de nuestra empresa y
  • hábitos, opiniones y experiencias pasadas de nuestros desarrolladores.

Básicamente, esto se reduce a: cada equipo (ya sea una empresa, un departamento o un proyecto de código abierto) es único. Tendrán diferentes prioridades y diferentes puntos de vista y, por supuesto, harán concesiones diferentes. Estas concesiones, y el estilo de código que resultan, son en gran medida una cuestión de gustos y no pueden demostrarse como "incorrectas" o "correctas". Los equipos solo pueden decir "hacemos esto porque funciona para nosotros" o "deberíamos cambiar esto porque no funciona para nosotros".

Dicho esto, creo que para poder mantener con éxito grandes bases de código a lo largo de los años, cada equipo debe acordar un conjunto de convenciones de código que consideren adecuadas para los aspectos mencionados anteriormente. Eso puede significar adoptar prácticas de Robert C. Martin, de otro autor, o inventar las propias; puede significar escribirlos formalmente o documentarlos "por ejemplo". Pero deberían existir.

Ejemplo

Considere la práctica de "dividir el código de un método largo en varios métodos privados".

Robert C. Martin dice que este estilo permite limitar los contenidos de cada método a un nivel de abstracción; como ejemplo simplificado, un método público probablemente solo consistirá en llamadas a métodos privados como verifyInput(...) , loadDataFromHardDisk(...) , transformDataToJson(...) y finalmente sendJsonToClient(...) , y estos métodos tendrían los detalles de la implementación.

  • A algunas personas les gusta esto porque los lectores pueden obtener una visión general rápida de los pasos de alto nivel y pueden elegir sobre qué detalles desean leer.
  • A algunas personas no les gusta porque cuando quieres conocer todos los detalles, tienes que saltar en la clase para seguir el flujo de ejecución (esto es a lo que JacquesB probablemente se refiere cuando escribe acerca de agregar complejidad).

La lección es: todos tienen razón, porque tienen derecho a opinar.

    
respondido por el Jens Bannmann 11.07.2018 - 20:57
13

Muchas bibliotecas de código abierto de hecho sufren de objetivamente malas prácticas de codificación y son mantenidas con dificultad por un pequeño grupo de contribuyentes a largo plazo que pueden lidiar con la legibilidad deficiente porque están muy familiarizados con Las partes del código que más frecuentemente mantienen. El código de refactorización para mejorar la legibilidad después del hecho suele ser un esfuerzo hercúleo porque todos deben estar en la misma página, no es divertido y no paga porque no se implementan nuevas funciones.

Como han dicho otros, cualquier libro sobre código limpio que indique algo en absoluto necesariamente contiene consejos que no están universalmente aceptados. En particular, casi cualquier regla puede seguirse con un celo excesivo, reemplazando un problema de legibilidad con otro.

Personalmente, evito crear funciones con nombre si no tengo un buen nombre para ellas. Y un buen nombre debe ser corto y describir fielmente lo que la función hace al mundo exterior. Esto también está relacionado con tratar de tener la menor cantidad posible de argumentos de función y no datos de escritura global. Tratar de reducir una función muy compleja en funciones más pequeñas a menudo resulta en listas de argumentos muy largas cuando la función era genuinamente compleja. Crear y mantener un código legible es un ejercicio de equilibrio entre reglas de sentido común mutuamente conflictivas. Leer libros es bueno, pero solo la experiencia te enseñará cómo encontrar falsa complejidad , que es donde se obtienen los beneficios reales de la legibilidad.

    
respondido por el Kafein 12.07.2018 - 18:21
7

La mayoría de los proyectos de código abierto están mal administrados. Obviamente hay excepciones a eso, pero encontrarás un montón de basura en el mundo de código abierto.

Esta no es una crítica de todos los propietarios / gerentes de proyectos cuyos proyectos estoy hablando, es simplemente una cuestión de tiempo utilizado. Estas personas tienen mejores cosas que hacer con su tiempo, como su trabajo remunerado real.

Al principio, el código es el trabajo de una persona y probablemente sea pequeño. Y el código pequeño no necesita estar limpio. O más bien, el esfuerzo necesario para limpiar el código es mayor que el beneficio.

A medida que pasa el tiempo, el código es más un montón de parches realizados por muchas personas diferentes. Los creadores de parches no sienten que el código sea suyo, solo quieren que se agregue esta característica o se corrija este error de la manera más fácil posible.

El propietario no tiene tiempo para limpiar las cosas y a nadie más le importa.

Y el código se está haciendo grande. Y feo.

A medida que se hace más difícil encontrar el código, las personas comienzan a agregar funciones en el lugar equivocado. Y en lugar de corregir errores, agregan soluciones alternativas en otros lugares del código.

En este punto, no es solo que a las personas no les importe, ya no se atreven a limpiar porque temen romper cosas.

He tenido personas que describen las bases de código como "castigo cruel e inusual".

Mis experiencias personales no son tan malas, pero he visto algunas cosas muy extrañas.

    
respondido por el Stig Hemmer 12.07.2018 - 12:10
3

Me parece que estás preguntando cómo funciona esto incluso si nadie está haciendo lo que está haciendo. Se supone que estamos haciendo. Y si funciona, entonces ¿por qué se supone que debemos estar haciendo estas cosas? >?

La respuesta, IMHO, es que funciona "suficiente" , también conocido como " empeora is better " philosophy . Básicamente, a pesar de la historia rocosa entre el código abierto y Bill Gates, ambos adoptaron de facto la misma idea, que a la mayoría de las personas les importa características, no errores .

Esto, por supuesto, también nos lleva a " normalización de la desviación " que conduce a situaciones como Heartbleed , donde, precisamente como si fuera a responder a su pregunta, una masiva, overgrown spaghetti stack de abierto El código fuente llamado OpenSSL fue " sin limpiar " para algo como diez años , terminando con un masivo fallo de seguridad que afecta a miles de millones de personas .

La solución fue inventar un sistema completamente nuevo llamado LibreSSL , que era va a utilizar el código clean-ish y, por supuesto, casi nadie lo utiliza .

Entonces, ¿cómo se mantienen los grandes proyectos de código abierto mal codificados? La respuesta está en la pregunta. Muchos de ellos no se mantienen limpios. Están parcheados al azar por miles de personas diferentes para cubrir casos de uso en varias máquinas extrañas y situaciones en las que los desarrolladores nunca tiene acceso para probar. El código funciona "suficientemente bien" hasta que no lo hace , cuando todos entran en pánico y deciden tirar dinero al problema .

Entonces, ¿por qué debería molestarse en hacer algo ' de la manera correcta ' si no hay nadie más?

La respuesta es que no deberías. Usted hace o no , y el mundo sigue girando independientemente, porque la naturaleza humana no cambia en la escala de un humano tiempo de vida . Personalmente, solo intento escribir código limpio porque me gusta la forma en que se siente hacerlo.

    
respondido por el don bright 13.07.2018 - 08:25
2

Lo que constituye un buen código depende del contexto, y los libros clásicos que lo guían son, si no demasiado viejos para hablar de código abierto, al menos parte de una tradición que libra la guerra interminable contra los códigos maliciosos internos. Así que es fácil pasar por alto el hecho de que las bibliotecas tienen objetivos completamente diferentes, y están escritas en consecuencia. Considere los siguientes problemas, sin ningún orden en particular:

  • Cuando importo una biblioteca, o desde una biblioteca, probablemente no soy lo suficientemente experto en su estructura interna para saber exactamente qué pequeña fracción de su caja de herramientas necesito para lo que sea que esté trabajando, a menos que esté Copiando lo que una respuesta de Stack Exchange me dijo que hiciera. Así que empiezo a escribir from A import (si está en Python, por ejemplo) y veo qué aparece. Pero eso significa que lo que veo en la lista debe reflejar las tareas lógicas que debo tomar prestadas, y eso es lo que tiene que estar en el código base. Innumerables métodos de ayuda que lo hacen más corto simplemente me confundirán.
  • Las bibliotecas están ahí para el programador más inexperto que intenta usar algún algoritmo del que la mayoría de las personas solo han oído hablar vagamente. Necesitan documentación externa, y eso debe reflejar con precisión el código, lo que no puede hacer si seguimos refactorizando todo para hacer felices a los seguidores de métodos cortos y de hacer una cosa.
  • Cada método bibliotecario que la gente toma prestada podría romper el código en todo el mundo con consecuencias desastrosas si se elimina o incluso se le cambia el nombre. Claro, quisiera que sklearn corrigiera el error tipográfico en Calinski-Harabasz , pero eso podría causar otro incidente del panel izquierdo . De hecho, en mi experiencia, el mayor problema con la evolución de la biblioteca es cuando se esfuerzan demasiado por adoptar algunas "mejoras" de buen código para estructurar todo.
  • En casa, los comentarios son en gran medida un mal necesario en el mejor de los casos, por todo tipo de razones que no necesito regurgitar (aunque esos puntos exageran un poco). Un buen comentario dice por qué funciona el código, no cómo. Pero las bibliotecas saben que sus lectores son programadores competentes que no podían, digamos, escribir, álgebra lineal a su manera de salir de una bolsa de papel. En otras palabras, todo necesita comentarios sobre: ¡por qué funciona! (OK, eso es otra exageración.) Por eso ve la línea de firma, el bloque de comentarios de 100 líneas, 1 línea de código que literalmente podría haber aparecido en la línea de firma (si el idioma lo permite, por supuesto).
  • Digamos que actualizas algo en Github y esperas para ver si tu código será aceptado. Debe quedar claro por qué funciona el cambio de código. Sé por experiencia que refactorizar para hacer que el camping sea más limpio como parte de un compromiso funcional a menudo significa mucho ahorro de líneas, reorganización y cambio de nombre, lo que dificulta el trabajo de los revisores sin sueldo y causa otros problemas mencionados anteriormente.

Estoy seguro de que las personas con más experiencia que yo pueden mencionar otros puntos.

    
respondido por el J.G. 11.07.2018 - 20:51
2

Ya hay muchas respuestas buenas: quiero dar la perspectiva de un mantenedor de código abierto.

Mi perspectiva

Soy un mantenedor de muchos de estos proyectos con menos de un gran código. En algún momento, incluso se me impide mejorar dicho código debido a problemas de compatibilidad, ya que las bibliotecas se descargan millones de veces cada semana.

Hace que el mantenimiento sea más difícil: como miembro central de Node.js hay partes del código que me da miedo tocar pero hay mucho trabajo que hacer independientemente y la gente usa la plataforma con éxito y la disfruta. Lo más importante es que funciona.

En código legible

Cuando dices:

  

En muchos de ellos, el código está muy lejos de los principios a los que se dirige para escribir código limpio, por ejemplo, métodos que contienen cientos de líneas de código.

Las líneas de código no son una gran medida de lo legible es. En el estudio que vinculé con Linux, se analizó el kernel y una encuesta entre programadores encontró que el código "regular" (código que la gente espera básicamente) y el código consistente es mejor que el código "limpio" en la comprensibilidad. Esto también se alinea con mi experiencia personal.

Algunos proyectos de código abierto no son muy acogedores

Linus "famoso" dijo que Linux no debería tener un depurador integrado porque las personas que usan depuradores no son lo suficientemente buenos como para trabajar en Linux y él no quiere atraer a más de ellos.

Personalmente, estoy totalmente en desacuerdo con su postura allí, pero también es algo que la gente hace.

    
respondido por el Benjamin Gruenbaum 13.07.2018 - 14:35
1

El software de código abierto no significa necesariamente que haya varios autores involucrados. Cuando un solo autor escribe un software (o unidad de software), las funciones largas aparecen con frecuencia.

Esto viene de la naturaleza del proceso de desarrollo. Un método simple se extiende a lo largo del tiempo, se agregan nuevas funciones y se corrigen errores.

Los métodos largos reducen severamente la comprensión de la funcionalidad para los nuevos autores. Sin embargo, con un solo autor, esto rara vez es un problema y el problema tiende a pasarse por alto. Otra naturaleza del código abierto es el hecho de que una gran cantidad de software no se desarrolla activamente, por lo tanto, no hay un trabajo de refactorización que, por ejemplo, dividiría los métodos complejos en múltiples métodos simples.

No ha mostrado ningún ejemplo pero, según tengo entendido, a menudo esto también está conectado al lenguaje de desarrollo. Algunos lenguajes hacen cumplir reglas de alineación estrictas desde el principio y pruebas de unidad pesada (o incluso TDD). Las pruebas de alineación y de unidad por lo general evitan ese problema (es difícil realizar pruebas unitarias de métodos complejos / largos).

En general, es más difícil limpiar el código si el software es desarrollado por un solo autor y otros colaboradores solo están solucionando pequeños problemas.

    
respondido por el Sulthan 13.07.2018 - 15:07

Lea otras preguntas en las etiquetas