Patrones de arquitectura de software
Arquitectura de capas (Layered Architecture)
Este tipo de arquitectura es la más común para la mayoría de software, y su punto central es la base de datos en casi todos los casos para persistir la información. Todo el código en esta arquitectura se organiza para que accedan por una capa superior y ésta pase la petición a una capa inferior hasta llegar a la capa de persistencia (base de datos, ficheros...)
En cada fase (o capa del aplicativo) se realiza una única tarea, como validar los datos introducidos, transformarlos...
Una estructura típica en esta arquitectura, sería: MVC (Modelo, Vista, Controlador), es el más común porque la mayoría de frameworks de desarrollo lo ofrecen como versión estándar al iniciar un desarrollo.
1. Capa persistencia (Base de datos)
Es la capa inferior, el corazón de nuestra aplicación. Ésta capa solo debe comunicarse con su capa inmediatamente superior. Es en ésta, dónde se persiste la información, sea en base de datos, ficheros, memoria...
2. Capa lógica negocio (Modelo)
En esta parte del aplicativo, tenemos toda la lógica perteneciente a nuestro negocio, el mapeo con las bases de datos si es el caso y los tipos de datos que existen en nuestra persistencia.
3. Capa intermedia (Controlador)
Capa que recibe una petición del usuario y contienen todas las reglas y métodos para transformar, parsear... que se intercambian entre la vista y el modelo.
4. Capa pública (Vista)
Es la capa superior que se compone de código HTML, CSS3, JavaScript por ejemplo, mezclado con código dinámico que nos proporciona el motor de vistas si es el caso.
Esta arquitectura puede contener más capas, como por ejemplo una capa de Service, Repository, ViewModel. Cuándo sumamos más capas a nuestro aplicativo aumentamos la complejidad del mismo, la curva de aprendizaje pero desacoplamos muchísimo más las capas y otorgamos más independencia a cada una de las fases del aplicativo.
Uno de los principales problemas, es que un desarrollador puede saltar una capa y acoplarse fuertemente produciendo una mezcla de responsabilidades sin ningún sentido.
Arquitectura por eventos (Event-Driven Architecture y Event Sourcing)
La mayoría de software, que existen en el mercado, están pensados para esperar que ocurra un evento para empezar a realizar las acciones asociadas. La ventaja de este tipo de arquitectura, es que se desarrolla una capa central que acepta toda la información/datos y éste se encarga de delegar ésta información al módulo encargado de tratar éstos datos. Esta acción se le conoce como "generar un evento".
Un ejemplo muy básico sería cuándo desarrollamos en front-end con javascript, dónde declaramos "escuchadores" (listeners) a las acciones del usuario, como un click del ratón, scroll de la página, carga de la página... Dentro de éstas funciones listeners sólo se ejecuta la acción determinada para tratar los datos de ese evento.
Es una buen arquitectura para un aplicativo que escala muy rápidamente o son entornos muy complejos, ya que permiten añadir nuevas funcionalidades con nuevos eventos, sin tener que adaptar código ya escrito.
Arquitectura de micro-kernel (MicroKernel Architecture)
La mayoría de aplicaciones tienen un grupo de básico de tareas que se utiliza frecuentemente en diferentes patrones y acciones del aplicativo. Para evitar tener que desarrollar una y otra vez éstas tareas, este patrón de arquitectura nos permite realizarlas una vez y compartir ésta base de código. A las otras capas de la parte superior de la aplicación se les suele denominar complementos o plugins y permiten extender la base de código.
Uno de los problemas que se encuentra cuándo uno desarrolla este tipo de arquitectura, es decidir que partes del código son introducidas en el microkernel y cuáles no, y éste proceso puede ser muy complicado, como también la modificación del código base una vez desarrollado.
A cambio nos ofrece una versatilidad par aplicaciones que se actualizan con frecuencia, y son son utilizadas por muchos usuarios. Quizá mas orientada a aplicaciones de escritorio que a un entorno web.
Arquitectura de micro-servicios (Microservices Architecture)
Una de las que está mas de moda últimamente, por el proceso de migración a la nube. Esta arquitectura nos facilita que nuestras aplicaciones crezcan, sean flexibles y manejables durante el tiempo evitando una estructura monolítica, en la cuál agregar cambios es muy complicado sin afectar a algún módulo de la aplicación. Puede parecerse a la arquitectura de eventos o microkernel pero en este caso, en cada microservicio se pueden asignar diferentes capacidades de procesamiento, persistencia, código... incluso se podría llegar a tener separado estos servicios en diferentes datacenter para un mayor escalado.
Esta arquitectura va muy unida al despliegue en "contenedores" que son orquestados por Kubernetes en la cualquier CLOUD público privado.
Una de las mayores ventajas es que permite escalar por separado partes del aplicativo con más demanda, por ejemplo la parte de login y registro de usuarios, independientemente de las notificaciones push.
Por poner un ejemplo si pensamos en youtube, un fin de semana el servicio de subida de videos escalaría vertiginosamente, ya que en estos días de la semana se suben muchos más videos que entre semana, siendo esto así, podríamos dotar de más recursos a la parte de subida de videos que a la de registro de usuarios.
Hay que tener en cuenta que cada microservicio es independiente y no puede estar acoplado a otro, es decir compartir una misma persistencia o cualquier otro elemento que los una.
Arquitectura de comandos (CQRS Architecture)
La peculiaridad de esta arquitectura, es que separa los modelos para leer y escribir. Bertrand Meyer lo definió de la siguiente manera:
- Consultas: Devuelven resultados sin cambiar el estado del sistema.
- Comandos: Cambian el estado del sistema.
La separación CQRS separa en diferentes capas las operaciones de consulta en una capa y de los comandos en otra. Cada capa tiene su propio modelo de datos y usa sus propios patrones y tecnologías.
Normalmente usando esta arquitectura, se suele ampliar usando Event Sourcing y DDD conjuntamente.
Arquitectura basada en espacios (Space based Architecture)
Muchas veces tenemos momentos, en que nuestra aplicación está dando el máximo de sí, y no puede procesar más peticiones. Para ello disponemos de esta arquitectura, que nos permite distribuir en muchos servidores la capacidad de procesamiento y almacenamiento. Una de las ventajas que nos ofrece, el almacenamiento de datos en la memoria distribuida. Es una arquitectura típica de despliegues en la nube.
Uno de los problemas ocasionados es que manejar transacciones es más complejo que en otras. Un buen ejemplo sería para temas de ingesta de datos en tiempo real con procesamiento de ellos.