Tienes pocos Controllers y tus Models se ven flacos

13 de enero de 2019

Hace poco estuve realizando una auditoría a un sistema fabricado por otro equipo de trabajo, parte del proceso de evaluación para verificar si podía o no aceptar el proyecto de continuidad, algo que la verdad suelo rechazar de forma tajante, pero al conocer la organización que estuvo trabajando en el proyecto (y confiar un poco en su experiencia técnica) decidí darle una oportunidad y ver si podía darle seguimiento o no.

Al final no acepté el proyecto, no porque no pudiese tomarlo, sino porque no me sentía cómodo aceptar el proyecto con ese diseño, ya que seguramente el cliente esperaría que yo fuese productivo desde el día 0, pero yo invertiría gran parte del esfuerzo inicial en “corregir” algunas prácticas incorrectas del proveedor anterior.

Siempre cuando intento diseñar la estructura de un proyecto, intento recordar aquel chiste que dice lo siguiente, el cual es atribuido a “John F. Woods” fn-1:

[…] Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. Code for readability.

En español sería algo como:

[…] Siempre programa como si el tipo que termine manteniendo tu código fuese un psicópata violento que sabe donde vives. Programa con la lectura en mente.

Anoche (12/01/2019) antes de dormir, me topé con éste Tweet de Rizqi Djamaluddin, quién tuve el placer de escuchar en el último Laracon Europe:

Esto me recordó aquella experiencia de hace algunos días mientras veía el código. Yo soy un fan del libro “Code Clean” de Robert C. Martin fn-2 y aunque el libro define distintas “buenas prácticas” generales muchas veces no sabemos como ponerlas en práctica en estos frameworks modernos, como Laravel o Rails.

Un problema que noto comúnmente es que solemos no crear suficientes archivos ni métodos y nos enfocamos en reutilizar los ya existentes. Es por esto, que creo que es útil poder compartir dos lecciones pequeñas a la hora de desarrollar en estos frameworks de estilo MVC:

  1. Intenta tener la mayor cantidad de Controllers
  2. La lógica de negocio nunca debe existir en el Controller, si no en el modelo

Analizaré un poco ambos casos a continuación:

#.Tienes muy pocos Controllers

Iniciemos con este punto. Algo que veo comúnmente es evitar crear suficientes Controllers en el sistema.

Hace muchísimo tiempo DDHH, creador de Rails, escribió el siguiente Tweet:

O en español:

Un problema común que veo en código de Rails: Muy pocos Controllers. Más Controllers con menos código obvia la necesidad para más patrones “lujosos” (fancy).

No puedo coincidir más en este mensaje.

La solución es simple: intenta crear la mayor cantidad de Controllers, que se encarguen de la menor cantidad de funcionalidad posible.

Una forma fácil de saber cuando requieres nuevos Controllers es cuando inicias el proceso de crear acciones distintas a las comunes (en Laravel serían a los que vienen en el Resource Controller), las cuales son únicamente:

  • Index
  • Create
  • Store
  • Edit
  • Update
  • Destroy

Si tu Controller tiene más acciones que estas, es muy probable que puedas restructurar tu código en distintos Controllers, para atender funcionalidad específica.

Al final, crear un Controller nuevo en laravel es tan fácil como

php artisan make:controller nombre

o en Rails:

rails g controller nombre

Si es tan fácil, ¿por qué no lo estamos haciendo hoy?.

Esta práctica es mejor explicada en el talk “Cruddy by Design” de Adam Wathan en el Laracon US 2017 fn-3.

#.Esos modelos se ven muy ‘flacos’ y tus Controllers muy ‘gordos’

Hay un patrón llamado “Fat models, skinny controllers” muy utilizado en la comunidad de Rails y Laravel. La intención no quiere decir que debamos tener, de hecho, Modelos abultados, si no que debemos extraer la lógica que no es parte del procesamiento del Request del Controller y enviarlo al Model.

Nota: La intención no es que los Models sean entonces “gordos”, prefiero un patrón más “Skinny Model, Skinny Controller”.

Veo la ruptura de esta práctica de forma muy común cuando otros ingenieros crean Controllers que se encargan de hacer cosas que no deberían, como por ejemplo:

  • Hacer validaciones (en Laravel sería mejor práctica utilizar Requests fn-4)
  • Subir archivos directamente
  • Crear filtros (para la DB)

#.Wrap up

Creo que si tuviera una forma de poder resumir todo esto sería a través de lo siguiente:

Intenta crear más archivos que hagan menos cosas y sigue las prácticas de Clean Code (en cuanto a nomenclatura, comentarios, simplicidad, DRY, estilo, etc.).