¿Cuántas veces hemos leído algo del tipo “Las mejores prácticas para Magento”? Incluso la documentación oficial nos ofrece algún tipo de muestra de esto mismo:
- Theme development best practices
- Best Practices for Extension Developers
- Performance Best Practices
- Programming Best Practices
Existen algunas otras prácticas que pocas veces se mencionan y discuten, y que ante su ausencia, es muy habitual encontrar escenarios particularmente nefastos. Sin dudas, existe una relación directamente proporcional entre el tamaño y vida del proyecto con el nivel de desastre. Peor aún si el proyecto pasó por más de una agencia.
De vez en cuando me toca hacer auditorías, a veces como un trabajo específico y veces como parte del ramp-up de un nuevo proyecto. Entiéndase nuevo como un proyecto que tocamos por primera vez y no como un proyecto que se comienza a desarrollar el día 0.
Si bien esto no es un problema exclusivo de Magento, es donde más me ha tocado y me toca verlo.
Voy a apoyarme en un ejemplo actual, de una tienda productiva (con buenos números en cuanto a ventas, tráfico, cantidad de servicios e integraciones).
Más allá de los módulos instalados vía Composer (cerca de 30 al día de hoy), dentro de app/code cuenta con unos 120 módulos (110 son totalmente a medida para el proyecto).
Para que quede claro, estos números son de lo más habitual y no califican como problemáticos o aterradores (hay casos mucho más complejos).
Las siguientes son prácticas que hace tiempo tomé como habituales, intentando reducir la intensidad de la patada en la ingle (o golpe en la cara o la expresión que prefieras para sentir dolor) para el que venga luego de mi.
README.md
No se trata aquí de recordar que hay que documentar, ya pasamos esa línea hace demasiado tiempo. Tampoco vamos a explicar que la documentación de los métodos y funciones tienen que explicar el por qué en lugar de lo que ya dice el código.
Cada vez que creo un nuevo módulo, le agrego el tan preciado README.md.
¿Y qué es lo que suelo incluir?. Trato de dejar la mayor cantidad de pistas sobre qué hace el módulo, por qué y qué opciones de configuración puedo usar y qué significan.
También es válido agregar las opciones de instalación, uso y desinstalación. Un ejemplo mínimo de esto pueden verlo en Make a README. Si mal no recuerdo, en Mugar tomamos eso de base.
Este es otro ejemplo real (el vendor está reemplazado por NDAs y esas cosas).
Cualquiera que necesite entender el módulo, además de poder leer el código, puede tener un pantallazo rápido de qué hace el módulo, cuando lo hace, de quién depende y dónde se configura. Lo más importante aquí, es saber qué hace y cuándo.
El objetivo final es tratar de ayudar a comprender y recordar qué, cómo y para qué existe el módulo.
CHANGELOG.md
El uso de un changelog puede ser más discutible.
Cuando los proyectos crecen mucho, los equipos rotan cual partido de Fútbol Americano y se usa la entropía como unidad de medida de complejidad; puede ayudar muchísimo.
En su momento terminé adoptando y adaptando lo propuesto por Keep a CHANGELOG. De esta manera, cuando se introduce un cambio en un módulo, la idea es dejar un registro de qué y por qué (y links si se puede).
La cantidad de trabajo que puede demandarnos es infinitamente menor a la energía necesaria si nos topamos con módulos de los cuales no sabemos nada y debemos reconstruir su historia mediante navegación del historial y llamadas con clientes y (en casos extraordinarios) proveedores anteriores.
Plugins, Preferences y Observers
Esto si es muy específico de Magento 2, pero como regla general, trato de mantenerlo cuando es viable.
Se nos ha repetido hasta el cansancio que la forma correcta de hacer un override de código core o de un módulo de terceros es mediante plugins. El plugin se usa como regla primera.
Sabemos también que los plugins tienen dos aspectos de los cuales tenemos que tener cuidado:
- No se pueden usar para todos los métodos. Pueden recordarlo aquí.
- El uso y abuso de plugins puede convertirse en una pesadilla para depurar.
Cuando un plugin no pudiera ser aplicado, quizás el uso de Preference nos permita lograr el cometido. (Siempre recordar que es un recurso del tipo «última línea de defensa», como bien se indica en la documentación).
Finalmente, y no por los mismos motivos, los Observers nos pueden permitir enganchar nuestro módulo con alguna sección del core o de otro módulo.
¿Qué pasa si aplicamos un Plugin o un Preference que puede alterar el flujo natural de una funcionalidad?.
En este caso no lo uso como una regla dura porque, como cuando nos preguntan sobre estimaciones, la respuesta es: depende.
Lo que trato de evaluar es si tiene sentido disparar un nuevo evento para que un futuro desarrollo se enganche con un observer. De esta manera, puedo estar quitándole peso al nivel de customización que deberá hacerse. Vale aclarar que, en pro de la performance, no es un recurso del cual se debiera de abusar.
He tenido escenarios intermedios, en donde posiblemente lo usaría pero al no tener certeza, he dejado el código (el trigger) comentado.
En todos los casos, esa información se agrega al README.md, para quien entra sepa que tiene un evento que se llama de tal manera y envía cierta información (y si estaba comentado, se explica también).
Programar para otros programadores
Todo se reduce a esta idea, a pensar que cuando termines tu tarea, alguien más la va a tomar y también va a tener deadlines. Además, el cliente también va a necesitar resolver con gran velocidad.
Incluso, en alguno de esos casos, el próximo podés ser vos, otra vez.
Si eso no sirve de inspiración suficiente, imaginen que los dos siguientes developers serán Jason Voorhees y Freddy Krueger, y ambos saben dónde vivís y a qué hora te acostás a dormir.