Clean Code - Parte 2

Clean Code - Parte 2

Sobre los métodos y funciones

·

4 min read

Esta es la segunda parte de la serie de Clean Code, donde analizamos una lista de sugerencias y buenas prácticas recomendadas. Esta vez sobre cómo estructuramos y planificamos un método o una función.

Sobre los métodos y funciones

  • ✅ Las funciones deben ser pequeñas.
    • Muy pequeñas… ¿Cómo lo conseguimos? Con los siguientes consejos.
  • ✅ Bloques dentro de if, else, while debieran ser de una línea de largo, y dentro de lo posible, llamen a una función.
    • Esto mantiene pequeña la función envolvente.
    • Esto también agrega valor documental, porque la función llamada con el bloque que la contiene tendrán un nombre descriptivo.
  • ✅ El nivel de espaciado (sangría) de una función no debe ser mayor a 2.
  • ✅ Las funciones deben hacer sólo una cosa, hacerla bien y sólo eso.
    • Si una función solo realiza los pasos que están un nivel por debajo del nombre indicado en sí misma, entonces la función está haciendo sólo una cosa.
    • Deben hacer lo que el nombre indica y nada más.
  • ✅ Las funciones no deben tener secciones dentro de ellas.
    • Si una función se puede dividir en secciones, entonces esa función no está haciendo una única tarea.
  • ✅ La función debe tener un nivel de abstracción.
    • Necesitamos asegurarnos de que las declaraciones dentro de nuestra función estén todas en el mismo nivel de abstracción.
    • Si responden a más de un nivel de abstracción, el nivel más bajo debe ser extraído a una función aparte (idealmente privada).
  • ✅ Regla de reducción. (Stepdown Rule)
    • La abstracción de una clase debe disminuir mientras la vamos leyendo hacía abajo.
  • ✅ Las sentencias switch deberían estar en una clase de bajo nivel de abstracción, aparecer una vez para crear objetos polimórficos y nunca repetirla.
    • Por ejemplo, puede estar en un Abstract Factory pero no aparecer en ningún otro lugar.
    • Esta sugerencia responde principalmente a la Programación Orientada a Objetos. Si tenemos varios casos de un cálculo particular en un método, es mejor abstraer esos cálculos diferentes en implementaciones diferentes de una clase abstracta.
  • ✅ Intenta tener funciones con 3 argumentos.
    • Trata de mantener los argumentos de 3 a 4.
    • El número ideal de argumentos para una función es cero (niladic). Le sigue con uno (monadic), seguido de cerca por dos (dyadic). Tres argumentos (triadic) debe ser evitado en la medida de los posible. Mas de tres (polyadic) requiere de una justificación correcta.
    • Prácticamente nunca debieran ser más de 4.
  • ✅ Cuando una función necesite más de 2 o 3 argumentos, envuélvalos en una clase propia.
  • ✅ Si una función está transformando sus argumentos de entrada, el resultado de esa transformación debiera aparecer como un valor de retorno.
    • Si una función tiene una operación de transformación sobre su entrada, entonces la salida de esa función debe ser el resultado de esa transformación.
    • Si una función está transformando su entrada, sólo debe hacer eso y nada más.
  • ✅ Las funciones no deben tener efectos secundarios (side effects)
    • La mutación de los parámetros de entrada debe ser evitada, una solución es configurarlos como final.
  • ✅ Argumentos de tipo bandera (Flag arguments) deben ser evitados.
  • ✅ Las funciones deben hacer o dar respuesta a algo (Command Query Separation)
    • Cualquier función debería cambiar el estado o retornar algo.
  • ✅ Prefiere las excepciones a retornar código de error.
    • Cuando retornas un código de error, creas un problema con el que debe lidiar el que está llamando la función de forma inmediata.
    • También crear enums de Errores aumenta la dependencia, varias clases terminan importando y usando dicho enum.
  • ✅ Extrae los bloques try/catch.
    • El control de errores es una cosa. Por lo tanto, una función que maneje errores no debería hacer nada más que eso.
    • Si la palabra try existe en una función, debería ser la primera palabra de la función y no debería haber nada después de los bloques catch/finally.
  • ✅ Evita la duplicación de código.