¿Cómo se podría saber si el código que se ha creado es fácilmente legible, comprensible y mantenible? Por supuesto, desde el punto de vista del autor, el código es legible y mantenible, porque el autor lo escribió y lo editó, para empezar. Sin embargo, debe haber un estándar objetivo y cuantificable por el cual nuestra profesión pueda medir el código.
Estos objetivos se cumplen cuando se puede hacer lo siguiente con el código sin el asesoramiento experto del autor original:
Es posible leer el código y comprender en un nivel básico el flujo de la lógica.
Es posible comprender a un nivel más profundo lo que está haciendo el código para incluir entradas, salidas y algoritmos.
Otros desarrolladores pueden realizar cambios significativos en el código original, como la corrección de errores o la refactorización.
Uno puede escribir código nuevo, como una clase o módulo que aproveche el código original.
¿Cómo cuantificamos o medimos la calidad del código para saber que es legible, comprensible y mantenible?
fuente
Respuestas:
Su compañero le dice después de revisar el código.
No puede determinar esto usted mismo porque, como autor, sabe más de lo que el código dice por sí mismo. Una computadora no puede decirle, por las mismas razones que no puede decir si una pintura es arte o no. Por lo tanto, necesita otro ser humano, capaz de mantener el software, para ver lo que ha escrito y dar su opinión. El nombre formal de dicho proceso es revisión por pares .
fuente
A veces, la mejor manera de saberlo es volver al código que escribió hace seis meses e intentar comprender para qué fue escrito.
Si lo comprende rápidamente, es legible.
fuente
Está:
La prueba real para 1. es (como dicen Alex en París y quant_dev ) que puede recuperarlo después de unos meses haciendo otra cosa.
La prueba para 2. y 3. es que alguien más puede recogerlo y descubrir cómo extender o corregir su código mientras sigue el diseño de su diseño. Si no pueden entender el diseño, cómo se relaciona con el espacio del problema o cómo se pretende usar su código , en su lugar, piratearán una solución a través del grano.
Hay reglas generales, principios (es decir, reglas generales que alguien escribió muy bien y dio un nombre) y todo tipo de sugerencias que pueden guiarlo en la dirección correcta, o alejarse de las trampas comunes. Sin embargo, ninguno de ellos garantizará las cualidades que estás pidiendo.
fuente
Si su código sigue los principios de SÓLIDO y SECO y tiene un buen conjunto de pruebas unitarias a su alrededor, probablemente sea mantenible.
¿Es legible? Léelo ¿Tienen sentido los nombres de métodos y variables? ¿Puedes seguir la lógica del programa sin problemas? Si la respuesta es sí, entonces el código es legible.
fuente
Leer cómo escribir un código que no se puede mantener: asegure un trabajo para toda la vida de Roedy Green, riéndose y aprendiendo.
El ensayo le ofrece numerosos ejemplos de cómo escribir código incorrecto, utilizando muchos ejemplos divertidos. Continúa explicando cómo utilizar la falta de ortografía creativa , la reutilización de nombres , la muy apreciada técnica de reutilización de nombres globales como privados .
De manera humorística, el ensayo te enseña cómo evitar todos los ejemplos de códigos ilegibles e imposibles de mantener.
En realidad, me resultó difícil creer que alguien escribiría código con similitudes con los ejemplos en el texto. Fue entonces cuando estaba recién salido de la escuela. Pero, después de trabajar durante unos años, veo el código del texto todos los días ...
fuente
A pesar de lo que parece, hay algunas medidas bastante objetivas que puede considerar. Libros como C ++ Coding Standards , Refactoring y Clean Code tienen largas listas de criterios para juzgar su código, analizando cosas como nombres significativos, tamaños de funciones, principios como acoplamiento y cohesión, diseño de objetos, pruebas unitarias, refinamiento sucesivo, etc.
La lista es demasiado grande para ser susceptible de una lista de verificación, pero lees el libro y eliges algunas cosas clave para trabajar, luego, después de varios meses, léelo nuevamente para mejorar aún más.
fuente
La prueba está en el pudín. Observe lo que sucede después de entregárselo a una persona razonablemente competente. Si no necesitan hacer muchas preguntas relacionadas con la dificultad del código, has hecho un buen trabajo.
Esta fue una primera lección de mi carrera. Un mentor dijo: "Documente todo, para que pueda escapar del programa más adelante. Si no anticipa preguntas cuando las respuestas están frescas en su mente, tendrá que resolverlas cuando no lo estén".
fuente
Leí todas las respuestas y noté que nadie mencionaba la complejidad del código.
Existe una estrecha correlación entre la complejidad del código y la legibilidad / mantenibilidad. Existen numerosos algoritmos de puntuación de complejidad de código, pero solo hablaré sobre cómo funciona la puntuación de complejidad de McCabe.
Básicamente, la puntuación de McCabe lee su código y calcula la cantidad de "rutas" únicas que hay a través de él. Si usa McCabe como su numerador y líneas de código como su denominador, también obtendrá una muy buena aproximación de "legibilidad".
Si tiene 10 líneas de código, y hay 300 rutas a través de ese código, ese es un código bastante difícil de mantener (difícil de cambiar de manera segura y fácil), y probablemente no sea muy legible. Por el contrario, si tiene 300 líneas de código, pero solo hay una ruta (no tiene condiciones), es legible y fácil de mantener.
Sin embargo, donde McCabe cae es en este último ejemplo. Si tengo 300 líneas de código sin condiciones, hay una muy buena posibilidad de que haya hecho "copiar / pegar reutilizar", y obviamente eso tampoco es algo bueno. Por lo tanto, existen medidas de todo el sistema que aplica además de McCabe, como la detección de código duplicado o casi duplicado.
fuente
Un punto que compartiría es si el código está integrado en "módulos", y cuando digo eso quiero decir que puede cambiar una cosa en un módulo y hacer que funcione fácilmente con el conjunto. Elimina los efectos entre cosas no relacionadas. También:
Recomiendo leer, El programador pragmático.
fuente
Algunas pruebas / indicadores:
Apaga el IDE. ¿Todavía puedes leer tu propio código? Cuando hay un error, ¿es bastante fácil rastrearlo a mano y descubrir en qué clase necesitarás un punto de interrupción para descubrir dónde está el problema? O cuando usa el IDE, ¿ni siquiera se molesta y pasa desde el principio?
La depuración a menudo se convierte en un juego de wack-a-mole donde arreglar un error crea 2+ más.
Desde la activación del gatillo hasta algo realmente útil que suceda, ¿cuántas llamadas de método toma? ¿Cuántos métodos pasan exactamente los mismos o la mayoría de los mismos parámetros exactos a otra llamada de método?
¿Cuántos archivos tiene que abrir para agregar un nuevo método simple a una clase?
Piensa en patrones y prácticas que hayas adoptado. ¿Lo hiciste porque tenían perfecto sentido o porque alguien te convenció de que "es la única forma de hacerlo?" o porque lo querías en tu currículum o porque algún desarrollador de rockstar lo dijo.
fuente
Puede detectar código fácil de mantener y legible buscando estas propiedades:
fuente
En una sola palabra, experiencia .
Para comenzar, debe haber puesto en el terreno, por lo que no puedo recomendar más que los programadores deberían tomarse el tiempo para leer libros como Refactoring , que proporcionará algunas de las herramientas más esenciales en un arsenal de programadores que mejorarán su capacidad para mantener el código y Clean Code, que ha sido escrito por algunos de los talentos más reconocibles en nuestro campo, y que describe casi todo lo que necesita comprender para garantizar que su código sea limpio y legible.
Sin embargo, ninguna cantidad de lectura es un sustituto de la experiencia duramente ganada. Realmente debe haber trabajado con el código por un tiempo para apreciar completamente la diferencia que puede hacer la atención a la calidad del código. Al experimentar el placer de trabajar con código limpio y bien factorizado, así como el dolor de trabajar con espagueti de código, aprendes a comprender mejor lo que los autores de estos libros realmente intentaban enseñarte, pero lo haces en un contexto más amplio del código de producción en vivo real, donde la calidad de lo que haces realmente importa e impacta tu capacidad de trabajar fácilmente con tu código a diario.
También ayuda tener un buen mentor o un compañero con la experiencia para confirmar que está poniendo el esfuerzo en escribir código a un alto nivel. Esta es solo una de las razones por las que las revisiones de código pueden ser tan útiles. El uso de herramientas de verificación y formateo de códigos también puede ser una ayuda muy útil para garantizar que mantenga las cosas limpias. Sin embargo, nada se compara con la experiencia obtenida a través de años de software de escritura, de tal manera que automáticamente te encuentras escribiendo código que es limpio, legible y estructurado simplemente para facilitar el mantenimiento, y todo porque te has acostumbrado a aplicar las mejores prácticas. largo.
fuente
Sin ser puritano: prefiera el estilo funcional. La mayoría de los idiomas en estos días (.NET, Ruby, Python, Javascript, etc.) lo admiten y lo promueven (por ejemplo, LINQ, underscorejs).
Es extremadamente fácil de leer.
Obliga a cada nodo a tener préstamos de intención única y enfocada a la claridad del propósito. Y debido a que cada tarea discreta está aislada, trivial, conectar y reorganizar nodos (operaciones) a diferentes fines es trivial. Esto se presta para facilitar el mantenimiento.
fuente
Código legible y mantenible: Código que, a primera vista, un programador puede comprender lo suficientemente bien como para poder:
Esto se reduce a 'claridad'. es decir, ¿cuántas preguntas tiene que hacer el programador a un segmento de código en particular antes de estar seguro de que 'entiende lo que hace lo suficientemente bien' para lograr la tarea actual sin causar efectos secundarios inesperados?
El libro 'Code Complete, de Steve McConnell' entra en esto con gran detalle.
Revisa varias métricas que puede usar para determinar si el código es de buena calidad.
Vea un ejemplo aquí: http://books.google.co.uk/books?id=3JfE7TGUwvgC&lpg=PT376&pg=PT389#v=onepage&q&f=false
fuente
Minimizar los efectos secundarios (idealmente no tener ninguno)
Una función que causa 3 cambios en estados fuera de su propio alcance es mucho más difícil de razonar y mantener que una que simplemente ingresa algo y genera algo más. No solo puede saber qué hace la función, debe recordar lo que hizo y cómo afecta a todas las demás funciones relevantes.
Para OOP, minimizar los efectos secundarios también significa clases con menos miembros, y especialmente menos miembros que pueden modificar el estado de la clase, ya que las funciones de los miembros pueden modificar estados más allá de los suyos y tener efectos secundarios (pueden manipular los elementos internos de la clase, por ejemplo). También significa clases con menos miembros de datos propios para que haya menos estado para que esos métodos puedan manipularlos y menos efectos secundarios que puedan causar.
Como un ejemplo simple, imagine tratar de diseñar una estructura de datos elegante que pueda mantener un
sorted
estado que utiliza para determinar si se realizan búsquedas binarias o lineales. En tal caso, podría ser útil separar el diseño en dos clases. Llamarsorted
a la clase no ordenada podría devolver una estructura de datos de otra clase que siempre mantiene su contenido ordenado. Ahora tiene menos efectos secundarios (por lo tanto, es menos propenso a errores y es más fácil de comprender el código), así como un código más ampliamente aplicable (el diseño anterior sería un desperdicio tanto en el procesamiento como en la eficiencia intelectual humana para arreglos pequeños que nunca necesitan ser ordenados).Evitar dependencias externas superfluas
Es posible que pueda implementar el código más conciso imaginable con la máxima reutilización de código utilizando 13 bibliotecas diferentes para realizar una tarea relativamente simple. Sin embargo, eso transfiere la sobrecarga intelectual a sus lectores al tener que hacerles entender al menos partes de 13 bibliotecas diferentes. Esta complejidad inherente debe ser apreciada de inmediato por cualquiera que haya intentado construir y comprender una biblioteca de terceros que requirió ingresar y construir una docena de otras bibliotecas para funcionar.
Esta es probablemente una visión muy controvertida, pero preferiría una modesta duplicación de código al extremo opuesto siempre que el resultado final esté bien probado (nada peor que el código defectuoso no probado duplicado muchas veces). Si la opción es entre 3 líneas de código duplicado para calcular un producto vectorial cruzado o extraer una biblioteca matemática épica solo para eliminar 3 líneas de código, sugeriría la primera a menos que todo su equipo esté a bordo con esta biblioteca matemática , en ese momento aún podría considerar escribir 3 líneas de código en lugar de 1 si es lo suficientemente trivial a cambio de los beneficios de desacoplamiento.
La reutilización del código es un acto de equilibrio. Reutilice demasiado y transfiera la complejidad intelectual de una manera de uno a muchos, ya que en esas 3 líneas de código simple que guardó anteriormente tiene el costo de exigir a los lectores y mantenedores que comprendan mucha más información que 3 líneas de código . También hace que su código sea menos estable, ya que si la biblioteca matemática cambia, también podría cambiar su código. Reutilice muy poco y también multiplique la sobrecarga intelectual y su código deja de beneficiarse de las mejoras centrales, por lo que es un acto de equilibrio, pero vale la pena mencionar la idea de que es un acto de equilibrio, ya que tratar de eliminar cada pequeña forma de duplicación modesta puede generar para un resultado que es tan difícil de mantener, si no más, que el extremo opuesto.
Pon a prueba la mierda
Esto es un hecho, pero si su código no maneja todos los casos de entrada y pierde algunos casos extremos, ¿cómo puede esperar que otros mantengan el código que escribió que ni siquiera entendió antes de que se transfiriera a sus ojos y manos? Es bastante difícil hacer cambios en el código que funciona perfectamente, mucho menos código que nunca fue del todo correcto en primer lugar.
Además de eso, el código que pasa pruebas exhaustivas generalmente encontrará menos razones para cambiar. Eso se relaciona con la estabilidad que es aún más un santo grial para lograr que la mantenibilidad, ya que el código estable que nunca necesita ser modificado no conlleva ningún costo de mantenimiento.
Documentación de interfaz
Priorice "qué hacen las cosas" sobre "cómo las hacen" si no puede dedicar el mismo tiempo a documentar ambas. Una interfaz clara que sea obvia en sus intenciones sobre lo que hará (o al menos, lo que se supone que debe hacer) en todos los casos de entrada posibles dará una claridad de contexto a su propia implementación que guiará en la comprensión no solo de cómo usar el código, pero también cómo funciona.
Mientras tanto, el código que carece de estas cualidades donde las personas ni siquiera saben lo que se supone que debe hacer es SOL, sin importar cuán bien documentados estén sus detalles de implementación. Un manual de 20 páginas sobre cómo se implementa el código fuente no tiene ningún valor para las personas que ni siquiera pueden entender exactamente cómo se supone que se debe usar en primer lugar y qué se supone que debe hacer en todos los escenarios posibles.
Para el lado de la implementación, priorice documentar lo que hace de manera diferente a los demás. Como ejemplo, Intel tiene una jerarquía de volumen límite para sus núcleos de trazado de rayos. Como trabajo en este campo, puedo reconocer la mayor parte de lo que hace su código de un vistazo sin examinar la documentación. Sin embargo, hacen algo único, que es la idea de atravesar el BVH y realizar intersecciones en paralelo utilizando paquetes de rayos . Ahí es donde quiero que prioricen su documentación porque esas partes del código son exóticas e inusuales en la mayoría de las implementaciones históricas de BVH.
Legibilidad
Esta parte es muy subjetiva. Realmente no me importa mucho la legibilidad de un tipo cercano a los procesos de pensamiento humano. El código más bien documentado que describe las cosas al más alto nivel aún me resulta difícil de seguir si el autor utiliza procesos de pensamiento extraños y complicados para resolver un problema. Mientras tanto, el código breve que usa nombres de 2 o 3 caracteres a menudo puede ser más fácil de entender para mí si la lógica es muy sencilla. Supongo que podrías hacer una revisión por pares y ver qué prefieren otras personas.
Estoy principalmente interesado en la mantenibilidad y, lo que es más importante, en la estabilidad. El código que no encuentra razones para cambiar es uno que tiene cero costos de mantenimiento.
fuente
Diría que una forma de saber sería si los nuevos miembros del equipo pueden recoger el código, comprenderlo y modificarlo para corregir defectos / cumplir nuevos requisitos con relativa facilidad.
fuente
Aquí hay una técnica que me gusta usar:
Muestre el código a uno de sus programadores pares y haga que le expliquen lo que hace. Esté atento a estas cosas.
1) Si no pueden explicar fácilmente el propósito de un bloque de código, refactorícelo.
2) Si tienen que saltar a otra sección de código para comprender la sección actual, refactorícela.
4) Cada vez que sientas ganas de hablar durante el proceso, esa sección del código necesita una refactorización. (El código no habla por sí mismo).
fuente
El código más fácil de mantener es el código que no está allí. Por lo tanto, en lugar de agregar al recuento de LOC, el nuevo código que 'reduce' el recuento de LOC (incluso si es menos difícil de mantener cuando se ve de forma aislada) podría hacer que la base de código total sea más fácil de mantener simplemente reduciendo su tamaño. Por lo tanto, la regla principal para el código mantenible:
En segundo lugar, no hay nada peor para la mantenibilidad que las dependencias ocultas. Entonces, para la regla número 2:
En tercer lugar, no todos los programadores tienen la misma habilidad para mantener o escribir utilizando técnicas o idiomas específicos más avanzados. Simulando toda la base de código, obtendrá una gran base de código que, debido a su tamaño, es difícil de mantener. Permitir características y modismos de técnicas avanzadas en todo el código hará que todo el código sea mantenible solo por desarrolladores senior, lo que también es malo. La clave para la mantenibilidad es la estratificación basada en el nivel de habilidad. Por ejemplo:
Bibliotecas de proyectos cruzados: desarrolladores senior, código completo de trucos / modismos / técnicas Bibliotecas específicas del proyecto y backend del sistema: desarrolladores intermedios, evite las cosas más avanzadas y difíciles de explicar. Las personas mayores revisarán este código en busca de oportunidades de mejora DRY.
Front-end: desarrolladores junior, use una guía de estilo estricta y un conjunto de técnicas de construcciones de lenguaje y modismos para evitar. Los desarrolladores de Medior revisarán este código en busca de oportunidades DRY y lógica empresarial oculta.
Entonces, para la regla número 3:
yo
fuente
Nunca es demasiado fácil intentar escribir código legible y fácil de mantener, pero no es difícil escribir un código fácil y fácil de mantener.
OOAD es una palabra de cuatro letras, pero es difícil de entender de una vez: siga el análisis y diseño orientado a objetos
Siempre comience con una buena recopilación de requisitos y la declaración exacta del problema
Debe mantener sus objetos sueltos y asegurarse de que su código no se repita: siga DRY [No se repita]
fuente