El Manifiesto del Programador Limpio o el Resumen del Libro de Código Corto de Robert Martin

Este artículo es una sinopsis del libro Clean Code de Robert Martin y mi comprensión de cómo debe ser Clean Code. No hay secciones sobre pruebas, TDD, qué arquitectura debería ser, etc. Aquí todo se trata de lo que debería ser el Código Limpio.





Sí, tal vez el tema de Clean Code ya está trillado, pero no todos están familiarizados con él y, además, no he encontrado análogos del contenido que figura en mi artículo.


General


No hay una verdadera forma y solución. Hay uno que es el más adecuado para una tarea específica.


Al resolver un problema, intente reproducir absolutamente todos los casos que puedan afectar esta tarea e implemente la tarea teniendo en cuenta absolutamente todos los casos.


Además, cuando resuelva el problema, intente pasar de lo contrario. Comprenda qué tipo de resultados desea obtener al final y cree sobre esta base el algoritmo mediante el cual se realizará la tarea.


Antes de enviar una tarea para liberar, verifique si funciona correctamente. ¿Hay algún error en esto? Esto se aplica incluso a los commits que se envían a su sucursal. El escenario más ideal es aquel en el que nadie podría encontrar errores en la funcionalidad que desarrolló.


Siempre piense en cómo puede hacer que su código sea más simple, más limpio y más legible.


  • ¿Qué casos puede tener una tarea?
  • ¿He tenido todo en cuenta?
  • ¿Qué podría salir mal?
  • ¿Qué se puede combinar?
  • ¿Hay alguna funcionalidad similar?
  • ¿Qué es superfluo aquí?
  • ¿Cómo hacerlo más fácil?
  • ¿Cómo hacerlo más legible?
  • ¿Cómo hacerlo más claro?

Código limpio


¿Cómo escribir código limpio y bueno? Es como escribir un libro. Primero haces un borrador y luego lo peinas al estado en el que te gustaría leerlo. Recuerde siempre que su código debe contar una historia para que el lector pueda entenderla.


Se entiende una entidad: una interfaz, una clase, un método, una variable, un objeto, etc.


  • El código limpio es simple, expresivo y enfocado en una tarea específica.
  • El código limpio es fácil de leer, como la prosa. Si este no es el caso, entonces vale la pena refactorizar.
  • El código limpio es fácil de modificar. No debe estar rígidamente vinculado a un montón de entidades. Cualquier entidad se puede cambiar fácilmente.
  • El código limpio pasa por una revisión mucho mejor. Si la revisión va con muchos comentarios, entonces no está limpia y debe ser refactorizada.
  • El código limpio siempre parece haber sido trabajado durante mucho tiempo. De cualquier manera que intentes mejorarlo, aún llegarás a la conclusión de que este código es el mejor. En consecuencia, el código limpio está pensado hasta el más mínimo detalle.
  • Regla Scout: Deje el lugar de estacionamiento más limpio que antes. Esto cambia fácilmente a la programación. ¿Ves el código sucio? Hazlo más limpio mientras resuelves tu problema. No debe dejarse llevar por esto, y si el código sucio está muy sucio, debe asignar una tarea y un tiempo separados para limpiarlo.
  • No tengas miedo de hacer cambios. Si desea hacerlos, entonces tiene razones para eso, lo que significa que hará que el código sea mejor y más limpio. Además, las pruebas mostrarán si hay algún error en su código (siempre que exista).
  • Cualquier entidad debe ser responsable de una función y solo de ella. Y ella debe realizarlo bien. Responsabilidad Única
  • Si una entidad es responsable inmediatamente de dos o más acciones, entonces su funcionalidad debe estar separada.
  • El código debe leerse de arriba a abajo.
  • En una arquitectura buena y competente, hacer cambios sin costos y esfuerzos significativos.
  • Eliminar código muerto. Un código muerto es un código que no se llamará bajo ninguna condición o un código que no se usa en ningún lado.

Nombres y divisiones


  • Utilice nombres claros y fáciles de pronunciar para cualquier entidad. Deben describir por qué existe esta entidad, qué hace y cómo se usa.
  • No tengas miedo de perder el tiempo eligiendo el nombre mejor y amigable. Ganará en el futuro trabajando o leyendo este código.
  • Si el nombre de la entidad no corresponde a su funcionalidad o el nombre no comprende lo que hace la entidad, entonces debe cambiarse el nombre al nombre más comprensible. Si esto es imposible, entonces algo está mal con su funcionalidad y necesita ser refactorizado.
  • La entidad, que tiene el nombre "Y", "Con", viola la responsabilidad individual. Vale la pena compartir la funcionalidad de dicha entidad. Pero esta regla a veces se descuida.
  • Textos incomprensibles, las líneas deben tomarse en variables y darles nombres claros.
  • Los nombres de los métodos deben contener un verbo que describa lo que hace este método y la palabra clave con la que funciona este método. Si el nombre del método no tiene un verbo, entonces esta entidad no debe ser un método o se le debe dar el nombre correcto.
  • Se deben evitar los mismos nombres para dos propósitos diferentes.
  • Si una entidad tiene un nombre similar al de otra entidad, entonces lo más probable es que su funcionalidad sea muy similar y que necesiten combinarse. Si no, sus nombres deben cambiarse para que no sean similares.
  • Si cambia el nombre mental de una entidad cuando lee el código para que pueda comprender más claramente su funcionalidad, cambie el nombre a este nombre mental.
  • Elija una palabra para un concepto. Será difícil comprender la funcionalidad cuando obtenga, recupere y obtenga los nombres. Mejor llegar a todas partes.
  • Un nombre largo y comprensible es mejor que uno corto pero incomprensible.

Las funciones


  • Las funciones deben ser cortas y compactas.
  • Las funciones deben ser muy cortas y muy compactas.
  • Un máximo aproximado de 20 líneas y 150 caracteres en una línea, si no cabe, entonces debe separarse.
  • Una función debe realizar solo una operación.
    • Ella debe hacerlo bien y no debe hacer nada más.
    • Si una función realiza solo aquellas acciones que están en el mismo nivel de abstracción, entonces la función realiza una operación.
    • Para determinar si una función realiza más de una operación, intente extraerle otra función, lo que no será una simple reformulación de la implementación.
  • Cualquier declaración condicional con opciones largas mediante switch-case, if-else se debe dividir o combinar sin duplicación, posiblemente en clases con implementaciones, y transferir la elección de implementación a la clase base, fábrica u otra persona.
  • Si, si no, mientras, etc. debe contener una llamada a una función. Será más legible, más claro y más fácil.
  • El número ideal de argumentos de entrada para una función = 0. Si hay más de tres argumentos de entrada, entonces debería considerar cómo deshacerse de ellos, por ejemplo, crear una clase para estos argumentos.
  • Cuantos más argumentos de entrada, más difícil se entiende la función.
  • La función a la que se pasa el argumento argumento, de la que depende la operación de la función, indica que la función realiza más de una operación. Dichas funciones deben dividirse en dos y llamarlas un nivel más alto.
  • Una función que modifica el argumento de entrada debe dar una referencia al objeto cambiado, y no solo modificarlo sin volver. String transform(String text)
  • Si la función debe cambiar el argumento de entrada, entonces deje que cambie el estado de su objeto propietario.
  • Si el argumento de entrada de la función no cambia (y se usa más en el código), debe copiar el valor del argumento y trabajar con la copia dentro de la función.
  • En lugar de devolver nulo, es mejor usar un objeto vacío - Collection.empty() o un objeto nulo - EmptyObject() .
  • Siempre trate de usar funciones no estáticas. Si esto no es posible, entonces use static.
  • Si hay un código que debe seguir uno tras otro, entonces pase los resultados de la primera función a la segunda para que alguien no cambie la secuencia de llamadas.
  • Utilice el polimorfismo en lugar de if / else o switch / case o when.
  • Evitar condiciones negativas.

Comentarios


  • No use comentarios si puede usar una función o variable en su lugar.
  • No comente sobre el código incorrecto, vuelva a escribirlo. No vale la pena explicar lo que sucede en un código incorrecto, es mejor hacerlo explícito y comprensible.
  • Los comentarios se pueden utilizar para transmitir información, advertencias sobre las consecuencias, pero no para explicar cómo funciona el código.
  • Utilice TODO y FIXME en los casos en que necesite tener en cuenta que el código debe mejorarse, pero ahora no hay recursos para esto.
  • Use //region REGIONNAME //endregion REGIONNAME , y si lo usa, piense si es posible dividir la región en entidades.
  • Código de documento complejo pero limpio.
  • No deje el viejo código comentado. Puede encontrarlo en el historial de confirmaciones, si es necesario.
  • Los comentarios deben ser concisos y claros. Los comentarios de información no deberían tener mucha información. Todo debe ser breve y al grano.

Formato y reglas


  • Siga el estilo de código adoptado en el proyecto.
  • Siga las reglas aceptadas en el equipo.
  • Sujeto a formato y estilo de código, el código será más fácil de leer y mejor. No es en vano que el libro se entregue al editor antes de publicarlo.
  • Debe tener herramientas automáticas que formatearán el código por usted.
  • El archivo fuente debe ser como un artículo de periódico. Hay un encabezado, una breve descripción en forma de parámetros y contenido en forma de funciones. Si este no es el caso, entonces debe cambiar el formato.
  • Las entidades relacionadas entre sí deben estar cerca, por ejemplo, en un paquete, para que sea más fácil navegar por el código.
  • Las variables de clase (campos) deben estar en la parte superior de la clase.
  • Las variables del método deben estar más cerca de su lugar de uso.
  • Las funciones deben estar en el orden de la llamada. Si uno llama al otro, entonces la función de llamada debe estar por encima de la llamada. Por otro lado, las funciones privadas de nivel inferior pueden estar al final del archivo y no interferir con la comprensión del código de alto nivel. Pero prefiero la primera forma.

Objetos y estructuras de datos


  • Debe trabajar con abstracciones para que la implementación se pueda cambiar fácilmente.
  • Debe trabajar con abstracciones, ya que el cliente que usa la funcionalidad no debe conocer los detalles de la implementación, debe saber qué implementación usar en cada caso.
  • Debe proporcionar una API con la que debe trabajar y ocultar los detalles de implementación, la estructura. Por lo tanto, será más fácil trabajar con tales entidades y agregar nuevos tipos de comportamientos, funcionalidades e implementaciones.
  • DTO - Objeto de transferencia de datos. Una clase que contiene solo datos y ninguna funcionalidad. Es necesario para transferir algunos datos. Un objeto de esta clase debe ser inmutable.

Clases


  • Las clases deben ser compactas.
  • Las clases deberían ser aún más compactas.
  • El nombre de la clase debe describir su responsabilidad. Desde aquí puedes calcular el tamaño de la clase.
  • El funcional de la clase debe corresponder claramente y encajar en el nombre de la clase.
  • Divide la conectividad en clases pequeñas. No debe haber una cohesión rígida y abundante; esto complica el apoyo y el desarrollo del proyecto.
  • Recuerde responsabilidad única. Una entidad debe tener una y solo una razón para el cambio.
  • Observar la encapsulación. El debilitamiento de la encapsulación siempre debe ser el último recurso.
  • Por lo general, declaramos que las variables y funciones auxiliares son privadas, pero a veces deben declararse protegidas y poder acceder desde la prueba.
  • Si un grupo de funciones pertenece a un determinado funcional, entonces este grupo de funciones puede y debe asignarse a una clase separada y usar su instancia.

Manejo de errores


  • Use Excepciones en lugar de devolver códigos de error.
  • El manejo de errores es una operación. Si hay una palabra clave try en la función, luego de los bloques catch/finally no debería haber nada más en la función.
  • Si tiene una enumeración que enumera errores, entonces es mejor deshacerse de ella y usar excepciones en su lugar.
  • Use excepciones no marcadas para indicar explícitamente el lugar donde hay problemas. No es necesario detectar dichos errores, sino que debe escribir código para que este error nunca exista.
  • Pase suficiente información junto con lanzar una excepción para que luego los usuarios de su código puedan entender lo que realmente sucedió.
  • En lugar de declaraciones condicionales con manejo de errores, es mejor lanzar excepciones y manejarlas.
  • No pase nulo a ninguna parte. Intenta evitar esto tanto como sea posible.
  • El manejo de errores es una tarea separada y no se aplica a la lógica principal del programa.

Fronteras


  • Siempre usamos algunas bibliotecas que a menudo nos dan una funcionalidad demasiado amplia o demasiado pequeña o entran en conflicto con la funcionalidad esperada, lo que hace que el código sea más desordenado en su uso final. Puede evitar esto simplemente aplicando patrones como Decorador, Adaptador, Fachada u otros.
  • Hay situaciones en las que necesita trabajar con una funcionalidad que está en desarrollo o que aún no se ha adaptado para su uso en el código de producción. En este caso, debe imaginar lo que espera de la biblioteca / esta funcionalidad y escribir su interfaz o crear una entidad con la que trabajará en su proyecto de la manera que lo necesite. Cuando la biblioteca se completa y se estabiliza, la adapta a sus estructuras preparadas y utiliza la funcionalidad preparada.

Epílogo


Este artículo solo proporciona pautas para escribir un Código Limpio. Por supuesto, pueden ser descuidados. Solo necesita comprender que cualquiera de sus decisiones debe tener argumentos a favor.

Source: https://habr.com/ru/post/es424051/


All Articles