Arquitectura en Angular
Tags: angular, architecture
Published: 2021-04-25 01:36:18

Crear una aplicación va mas allá de escoger nuestro Framework o librería favorita, sea por preferencia personal o por ser la herramienta más usada en el mercado, para empezar a estructurar nuestra aplicación.

Una frase cuyo autor es anónimo, dice:

`"Cuando quieras construir algo que perdure, procura que los cimientos sean sólidos"`

Esa frase, se puede aplicar en la construcción de nuestras aplicaciones, y es bueno conocer bien los cimientos, las bases o como algunos dirían las piedras angulares, que nos permiten no solo crear una arquitectura sólida, también algo que puede perdurar y cumpla con el objetivo para el cual la creamos.

Angular es un Framework que en sus inicios desde la versión AngularJS, nos llevo a aprender no solo las bases del desarrollo Web, también nos impulsó a conocer sobre el **MVC — Modelo-Vista-Controlador**.

En su versión 2, pasada la primera a un segundo plano, teniéndose en cuenta que **Typescript** es el lenguaje predominante para esta versión, nos dimos la tarea de aprender a tipar nuestros datos de una forma más estricta, y aprender sobre el **MVVM — Modelo-Vista-Vista-Modelo**, donde sobresale el concepto del **2-way binding**, y la idea perdurable allí era el desacoplamiento de la interfaz y la lógica de negocio.

#Aplicación de Angular

Una aplicación de Angular es un conjunto de legos unidos, que tiene diferentes técnicas que nos permiten usar la arquitectura. Esos legos son los bloques de construcción de la aplicación.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g1i4yy4ukog9qofzpleq.png)

Según la documentación oficial de Angular, la arquitectura de una aplicación, se basa en ciertos conceptos fundamentales. Los bloques de construcción básicos del marco angular son componentes angulares que están organizados en NgModules.‌


NgModules recopila código relacionado en conjuntos funcionales; una aplicación de Angular está definida por un conjunto de NgModules.

Una aplicación siempre tiene al menos un módulo raíz que permite el arranque y, por lo general, tiene muchos más módulos de funciones.‌

Siguiendo este marco de Angular hay unos conceptos básicos que es fundamental aprender para crear nuestras aplicaciones como son: Módulos, Componentes, Servicios; que en conjunto con otros conceptos como Routing, Schematics, Directivas, Formularios y algunos patrones (DI), entre otros, que nos ayudan a crear nuestras aplicaciones en Angular.‌

Basado en ese marco inicial, en la página oficial podemos encontrar un diagrama, que enseña cómo se relacionan estas piezas básicas y de esta forma vamos armando nuestro rompecabezas o nuestra aplicación de legos.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bl1egl4aoxm8ihjyubbx.png)

Los conceptos claves de la arquitectura en Angular son:‌

* La estructura de Módulos.
*bOrganización de los Componentes.
* Librerías personalizadas (Rehusar algún componente o servicio a través de toda la aplicación o entre aplicaciones).
* Técnicas de comunicación entre componentes.
* RxJS (Observables).
* State Management o Administración del estado.
* Decoradores personalizados, Pipes, entre otros.‌

Podemos usar esos conceptos o alguno de ellos, para crear una aplicación con una buena arquitectura.‌

No hay una única forma de crear la arquitectura de nuestra Aplicación, pero lo más importante es **KISS**- y no me refiero a una banda de rock-.‌

“**Keep It Simple, Stupid**” ó “**Mantenerlo Simple**” (La última palabra sobra en su traducción)‌.

La idea de este principio es crear soluciones que nosotros y otros puedan entender.‌

Hay una frase muy útil de recordar de Martín Fowler:


`“Cualquiera puede escribir código que una máquina pueda entender. Pero solamente un buen programador es capaz de escribir código que otras personas también entiendan”.`

Tips alusivos de este principio son:‌

* **Mantener los métodos y Clases pequeñas** (pocas líneas de código). Una vez un desarrollador me dijo que una buena forma es por archivo intentar crear hasta 100 líneas, si me pasaba de esa meta es posible que mi código necesitaba ser refactorizado o había alguna funcionalidad en ella que estaría mejor ubicada en otro lugar.
* **Nombres Claros para nuestras variables, métodos o funciones y clases**. Es bueno usar nombres que sean lo suficientemente claros para no necesitar comentarios que expliquen qué se pretende hacer. 
* **No reutilizar variables o dar dos significados a una variable**. Es bueno evitar shadowing o sombreado, en nuestras variables o darle demasiadas funciones a una, para evitar confusiones.
* **Dividir el problema en partes más pequeñas**. Encontrar la solución a problemas es nuestro objetivo, a veces tomamos el todo, en lugar de dar soluciones a partes especificas. Es bueno dividirlo para prestar atención al detalle y poder analizar diferentes aspectos.
* **No abusar de los comentarios**. Si requieres documentar mucho de tu código, quiere decir que tal vez no es lo suficientemente entendible para otros desarrolladores. Es bueno hacer pequeños comentarios, solo si es necesario, lo ideal es que tus funciones y variables sean claros, como se mencionó antes.
* **Evitar la duplicidad**. Es recomendable que cuando veas código duplicado crees una solución reusable de ello, es bueno evitar copiar y pegar el código en diferentes lugares para ahorrar tiempo.
* Aplicar más principios. Como el principio **SOLID**.

**S** — Single Responsibility Principle (SRP) o Principio de responsabilidad única.
**O** — Open/Closed Principle (OCP) o Principio de abierto/cerrado.
**L** — Liskov Substitution Principle (LSP) o Principio de sustitución de Liskov.
**I** — Interface Segregation Principle (ISP) o Principio de segregación de la interfaz.
**D** — Dependency Inversion Principle (DIP) o Principio de inversión de dependencia.

# Aspectos a considerar en la Arquitectura

Antes de construir una aplicación debemos pensar en ciertos aspectos importantes que son necesarios, e incluso hablando desde un rol diferente a desarrolladores, como arquitectos de un edificio, debemos seguir los planos; pero en una aplicación no tenemos un único plano para construirla.‌

Pero es importante tener en cuenta lo siguiente:‌

* **Visión general de nuestra aplicación**. Conocer los objetivos, para qué se va a usar la aplicación, como la van a usar, entre otros aspectos que nos sirvan para darnos una gran idea de lo que vamos a construir. Analizar todos los requerimientos.
* **Características de la aplicación**. Es muy importante listar todas las características. Usuarios, Login, Empresa, entre otros.
* **Seguridad**. Habla de la seguridad, reglas en el servidor, como será la comunicación de nuestra API en la aplicación, se va a usar un Token (**HttpInterceptor**), o que otro método.
* **Autenticación**. Se va a manejar una API para la autenticación o vamos a integrar nuestra aplicación con alguna librería, third-party option o servicio en la nube?
* **Comunicación con los servicios**. Como nuestra aplicación se va a comunicar con el servidor? HTTP? Web Sockets? Restful services.
* **Modelos de Datos**. ¿Qué va a pasar en los componentes? estamos obteniendo lo que necesitamos en la API? ¿Cómo podemos obtener una pequeña parte de todo lo que obtenemos en la API?
* **Features Components o Características de Componentes**. Como vamos a organizar nuestros componentes, vamos a usar el patrón presentacional. ¿Cómo vamos a manejar la comunicación entre ellos?
* **Shared Functionality o funcionalidad compartida**. Tenemos que definir varios aspectos sobre la aplicación, si vamos a compartir diferentes funcionalidades a lo largo de nuestra App. Componentes como un menú, un modal o 3rd party libraries: Material, NGPrime, otra.

Adicional a las anteriores, es bueno también considerar lo siguiente en tu aplicación:‌

* **Accesibilidad**. Es importante hacer accesible nuestra aplicación a todos y esto nos ayuda a considerar más aspectos.‌
* **i18n**. La internacionalización es un aspecto que puede afectar enormemente tu aplicación, es bueno considerar si se desea que esté en varios lenguajes y esto implica analizar qué herramientas vamos a usar y cómo estructurar el proyecto.‌
* **Unit testing o pruebas unitarias**. Qué herramientas vamos a usar, vamos a usar karma.‌
* **End-to-End testing**. Se va a usar Cypress. Esto podría afectar un poco el código en cuanto a que se deben tomar algunas decisiones como si se van a usar Ids o las etiquetas, para hacer las pruebas.‌

Se pueden considerar más aspectos, de acuerdo a las necesidades que vayan surgiendo o las que se creen en el equipo de trabajo. Las anteriores podrían ser nuestra base, y una ayuda para la forma en cómo crearemos el mapa de la arquitectura de nuestra aplicación.


Una buena práctica es crear una plantilla, de los puntos claves a definir en cada proyecto, nos ayuda a ahorrar tiempo para no tener que volver a pensar en cuáles son los principales aspectos que debemos considerar a la hora de iniciar.


Como por ejemplo la siguiente:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9dnvomgwkfknszltp65f.png)

Puedes crear una tabla como la anterior, analizar tu aplicación e ir describiendo que vas a usar, o cómo vas a estructurar cada uno de ellos después de análisis exhaustivo y el levantamiento de requisitos pertinentes que se realizó.

En la arquitectura de nuestras aplicaciones se suele hablar de algunas metodologías, estructuración de componentes, la modularidad, principios, patrones de diseño, entre otros, es importante tenerlos en cuenta a la hora de iniciar nuestros proyectos, y sobre todo la documentación oficial, en ella podemos encontrar la guía de estilos que nos ayuda a implementar buenas prácticas, además de la guía para usar los legos o elementos de Angular, que vamos a ir implementando en nuestra aplicación.

#Guía de estilos

Teniendo en cuenta los conceptos básicos, la guía de estilos de Angular nos da una pauta para convenciones, nombramientos, buenas prácticas y patrones que es importante conocer y seguir las recomendaciones que la guía nos enseña, para crear buenas aplicaciones.‌

Podemos encontrar la guía en la siguiente URL: [https://angular.io/guide/styleguide](https://angular.io/guide/styleguide)

Podemos destacar algunas de ellas como:‌

* **Convenciones en el código**, como prácticas, organización de los archivos, indentación, comentarios, declaraciones.
* **Reglas en los nombres**, usar mayúsculas para iniciar los nombres, minúsculas, Camelcase, separar los nombres por guiones, nombrar los archivos seguidos del tipo de archivo, entre otras.
* **Estructura de la aplicación**, manejar un directorio raíz para toda la aplicación, crear carpetas por cada característica de la aplicación, o tener carpetas para manejar los assets. Principio **LIFT**, para estructurar la aplicación de tal manera que se pueda Localizar (**L**ocate) el código rápidamente, Identificar (**I**dentify) el código rápidamente, mantener la estructura plana (**F**lattest), y Tratar (**T**ry) de mantenerte **DRY** (Don't Repeat Yourself) o **T-DRY** (Try to DRY).
* **Organizando los módulos**, en este definimos si deseamos crear un módulo por cada característica de nuestra aplicación, crear el módulo App, módulos reusables.
* **Creando y usando los componentes**. Cómo extraer los templates o hojas de estilos de los componentes, usar los decoradores Input/Output, añadir la lógica presentacional en los componentes.
* **Creando y usando los servicios**. Usar los servicios como “Singletons”, con el mismo injector. Usar los servicios para compartir datos y funcionalidades.
* **Lifecycle hooks**. usar el ciclo de vida para usar los eventos importantes de Angular.

#¿Cómo definimos la arquitectura de nuestra aplicación?

* Analiza los requerimientos. Necesitamos hacer un análisis de lo que se desea hacer, es posible que nuestra aplicación crezca y se deba reestructurar, pero de los requerimientos actuales se debe pensar en crear código que no posea mucha complejidad, que se pueda escalar y que los nuevos integrantes del equipo puedan entender, para que sean partícipes activos de la aplicación.
* Fácil de mantener. Es este punto ayuda mucho el anterior, es bueno pensar en componentes aislados en su lógica, pero a veces de la prisa lo olvidamos, es bueno siempre recordar que la aplicación va a crecer y se debe hacer un alto a tiempo en el código, pensar en una solución que sea entendible y fácil de mantener para todos.
* Desarrollar funciones o características que nos ayuden a estructurar la aplicación, donde algunas ayudan al mantenimiento del estado de la aplicación. 
* Se debe definir el alcance del estado, no todos los estados deben ser visibles en toda la aplicación, es bueno aprender a ubicar de acuerdo al tipo de estado su lugar correcto.
* Separar el contenedor de la presentación, se debe definir que componente es solo para mostrar información que no tendrá lógica compleja y cual se encargará de manejar la lógica a mostrar en el presentacional.

# Referencia

[Angular Architecture and Best Practices **Dan Wahlin**](https://app.pluralsight.com/library/courses/angular-architecture-best-practices/table-of-contents)


#Conclusión

Cuando creamos nuestras aplicaciones en Angular, nos surgen algunas dudas para crear la estructura de carpetas, que metodologías usar o cual es la tecnología idónea para hacerla. 

Aprender bien los fundamentos de Angular, seguir su guía de estilos, la documentación y las buenas practicas, nos permite crear aplicaciones que puedan ser escalables y perdurables.

Te recomiendo los tips que se mencionan en este artículo, para poder darnos una buena idea de como crear la estructura de nuestro proyecto, además de no dejar de lado los patrones de diseño y metodologías de desarrollo de Software, que nos ayuda en la tarea de crear una buena arquitectura.

Te invito a seguirme en twitter con el handle: @vanessamarely