• No se han encontrado resultados

Vista de descomposición 1. Representación primaria

5. Arquitectura y Diseño

5.3. Vistas de Módulos

5.3.2. Vista de descomposición 1. Representación primaria

5.3.2. Vista de descomposición

App : Es el directorio que contiene el corazón del código vinculado a la aplicación. Se decide presentar este elemento en este diagrama, ya que se utiliza para agrupar un conjunto cohesivo de paquetes que representan el sistema y al incorporarlo refleja en gran medida cómo se estructura el código [55] .

Providers : Los providers son parte de la esencia del framework . En este paquete se encuentran todas estas clases que básicamente se encargan de hacer el bootstrapping (registro) tanto de servicios personalizados como del core de Laravel. Esto incluye desde crear enlaces entre abstracciones e implementaciones de servicios, eventos y escuchas, y middlewares, hasta rutas. Es el lugar central de configuración del proyecto y es un lugar central en cuanto a entender el ciclo de vida de cada interacción [56] .

Enums : El equipo creó un paquete específico que contiene todos los enums del sistema. Este tipo no primitivo de PHP, fue incorporado a partir de su versión 8.1 [57] .

Http /Requests/Resources : Contiene controladores, middlewares , form requests [58] y api resources [59] . Toda la lógica de manejo de requests entrantes al sistema se encuentra agrupada dentro de este paquete.

Events y Listeners : Los eventos contienen las clases relacionadas con eventos mientras que los listeners a agentes de escucha. Un listener puede escuchar a más de un evento y un evento puede tener más de un listener . Estos se vinculan a través del EventServiceProvider y es una gran forma de agregar flexibilidad y desacoplar el sistema [60] .

Notifications : Las notificaciones a diferencia del mail , son mucho más genéricas y permiten lanzarse de forma automática ante cierta situación que acciona el usuario, por ejemplo al momento de registrarse, enviar el mail de confirmación [61] .

Mail : Contiene las clases que representan emails . Estas clases permiten encapsular toda la lógica de construcción de mails en una sencilla clase altamente cohesiva [62] .

Database : Contiene las migraciones [49] , factories [63] (sirvió para generar datos de prueba tanto para la base como para tests ) y seeders [64] .

Tests : Contiene todos los tests automáticos, tanto unitarios como funcionales [65] .

Routes : Contiene los archivos vinculados a las diferentes rutas que existen en la aplicación [66] .

Config : Este paquete agrupa todos los archivos de configuración [67] .

Resources : Contiene todas las vistas y archivos de CSS y Javascript [55] . En este sistema, el frontend está separado del backend por lo que las únicas vistas son las que se generan para los mails .

Middlewares, Controllers , Services , Models : Ver catálogo de elementos del punto anterior.

5.3.2.3. Decisiones de diseño Patrón Cliente-Servidor

En el diagrama de capas se puede ver que no se incluyó una capa de vistas en el backend y esto en realidad se debe a que las vistas no se incluyeron dentro de la aplicación de Laravel a pesar de ser un framework full stack . Laravel cuenta con un sistema basado en templates llamados blades [68] que facilitan enormemente el desarrollo de componentes visuales. De hecho, Laravel permite construir un frontend moderno gracias a Vite [69] , una herramienta que permite compilar archivos de CSS y Javascript a archivos listos para producción. El uso de esta herramienta se hace a través de un plugin , y permite generar un entorno óptimo para el desarrollo de frontend pudiendo mezclar fácilmente lo mejor de los blades con frameworks populares como Vue o React. Dicho todo esto, el equipo no dio por obvio que el frontend debía desplegarse de forma independiente o incluso tener su propio repositorio. Se decidió priorizar la escalabilidad y el mantenimiento para favorecer la separación de

responsabilidades y finalmente usar el patrón cliente-servidor. El equipo cree que el backend

y el frontend deben poderse escalar y mantener por separado, además de que en etapas

tempranas del proyecto aún se estaba decidiendo si crear una web o una app mobile y en caso de que esto cambiara por algún motivo, tener el frontend en el mismo código que el backend impediría esta flexibilidad y reutilización por lo que la decisión sería future proof . Algunos otros beneficios son que la conexión entre el cliente y el servidor se hace de forma dinámica y a priori el servidor no tiene conocimiento de sus clientes, por lo que hay bajo acoplamiento entre el servidor y sus posibles clientes (así como tampoco hay acoplamiento entre clientes, el equipo usó tanto el navegador a través del frontend , como Postman para probar la

funcionalidad del backend ).

Patrón MVC

Laravel es un framework que por defecto, sigue la arquitectura MVC [70] . Esto se ve

reflejado en que los modelos son quienes directamente interactúan con la base de datos y los controladores con las vistas, las cuales a su vez reciben las interacciones del usuario y son las responsables de mostrar todo lo que el usuario ve. Como se vio en el diagrama de capas, el equipo extendió el comportamiento del Controller agregando una capa de servicios para la lógica de negocio en vez de que la haga directamente el controlador para favorecer aún más el SRP y mantener un código más cohesivo y menos acoplado. La separación de estos

componentes permite una mayor modularidad y, por tanto, reduce la complejidad en general, facilitando la mantenibilidad y la facilidad de prueba resultando en una mejor calidad de software en cuanto a modificabilidad y testeabilidad.

Ilustración 46 - Diagrama genérico de la arquitectura MVC [70] . Monolith-Firs t: El uso de microservicios no aplica al contexto del proyecto.

Vale la pena comentar que el equipo decidió no usar una arquitectura orientada a

microservicios [71] de forma consciente. Se tomó como referencia diferentes artículos de Martin Fowler, ingeniero de software de gran renombre especializado en análisis y diseño de software , para justificar la no división de la arquitectura en microservicios tomando un

enfoque Monolith-First [72] . Este enfoque propone comenzar con una arquitectura monolítica independientemente de la complejidad del problema. Esto permitió hacer un desarrollo mucho más veloz e ir evaluando la complejidad del dominio al mismo tiempo que se llega al

mercado. Este proyecto tiene un marco temporal ajustado por lo que favorece al equipo menor complejidad a la hora de hacer el desarrollo.

Ilustración 47 - Ilustración presentando ventajas de una arquitectura inicial monolítica [72] . Dado el alcance del proyecto, el tamaño del equipo, y analizando el balance de los pros y contras de basarse en esta arquitectura es que se decidió hacer uso de una arquitectura monolítica.

El equipo no encontró razones para escalar y desplegar de forma independiente los diferentes módulos basados en dominios que podría tener el sistema. En vez de eso, se prefirió escalar un único servicio, siendo más eficiente en costos, tiempo y sobre todo simplicidad. Además, el equipo no planea cambiar de tecnologías a ningún microservicio que justifique separarlo.

También se decidió favorecer la velocidad de desarrollo que implica un único backend contra varios microservicios, estando en etapas tempranas del proyecto donde aún la incertidumbre es mayor y el dominio es nuevo, una arquitectura monolítica permitiría al equipo una mejor adecuación al cambio. Agregando al punto anterior, al ser sistemas distribuidos, existe la consistencia eventual debido a que las llamadas remotas pueden enlentecer o incluso fallar.

Finalmente, manejar varios servicios en simultáneo y mantenerlos requiere un equipo experimentado en microservicios y/o de mayor tamaño que las 3 personas que lo componen en este caso. Lo que sí se favorece es la fuerte separación en módulos, el equipo decidió

hacerlo en capas y mantener un bajo acoplamiento en ese sentido (ver 5.3.1. Vista de Capas ) [73] .