Skip to main content
Clean Architecture

Clean Architecture

Introducción

Cualquier persona que haya trabajado como desarrollador durante, al menos, unos meses probablemente se ha enfrentado a situaciones en las que la aplicación en la que estaba trabajando, que al principio era amigable y estructurada, ha crecido tanto y tan rápido que contiene clases de más de 800 líneas de código. En ellas se pueden encontrar elementos duplicados, métodos que realizan quince acciones diferentes y poco a poco van surgiendo dificultades para encontrar dónde se realizan determinadas acciones o incluso para realizar tareas que deberían ser triviales como crear test unitarios.

Plantear una nueva funcionalidad o una ampliación de las ya existentes empieza a ser inviable sin la perspectiva de invertir tiempo en refactorizar, y es en este momento en el cual empiezan a surgir incógnitas como: ¿qué ha pasado con mi proyecto?, ¿cómo hemos podido llegar a esta situación?

Modelo-Vista-Controlador

 

Tras enfrentarnos a este problema, probablemente empecemos a investigar sobre arquitectura de software o hablemos con desarrolladores experimentados. En ese camino, lo más probable, es que nos acabemos encontrando con las famosas siglas MVC (Model-View-Controller), vamos a intentar entenderlas:

  • Model: son las clases que definen los datos de nuestra aplicación.
  • View: es la interfaz propiamente dicha en definitiva el punto de entrada del usuario a nuestro producto.
  • Controller: son las clases en las que se van a realizar la captura de los eventos que suceden en la interfaz actuando en consecuencia. Además, de realizarse las interacciones con el modelo de la aplicación.

Esta sencilla arquitectura no es la solución a todos nuestros problemas ya que si se aplica en sentido literal pueden aparecer dificultades. En pocas semanas los controladores que venían con la promesa de solucionar nuestros problemas serán clases de miles de líneas que además de responder a eventos de la interfaz, realizarán llamadas a servicios web, obtendrán y almacenarán información en BBDD, realizarán validaciones, aplicarán reglas de negocio, y todo esto entre otras muchas tareas. Finalmente, habremos implantado una arquitectura Massive-View-Controller, ya que ahora tendremos controladores que tendrán los mismos problemas que pretendíamos solucionar al principio.

Un poco de reflexión

 

Ahora que parece que tenemos claro que existe un problema vamos a plantear unas sencillas preguntas, sobre situaciones del día a día:

  • ¿Pondríais en vuestra cocina el armario de la ropa?
  • ¿Pondrías la ducha en el recibidor?
  • ¿Tendríais la tv colgada encima de la vitro y la campana extractora de humos encima del sofá?

Lo lógico tras estas preguntas es que penséis que me estoy equivocando de artículo, pero… ¿por qué si os escandalizan esas asunciones sobre la distribución del hogar, os parece lógico realizar llamadas a servicios web en el mismo fichero que capturáis los eventos que suceden en la interfaz? Desde un punto de vista de ingeniería del software es tan extraño como cualquiera de las anteriores preguntas.

Clean Architecure al rescate

 

Clean Architecture es un nombre popularizado por Robert Cecil Martin, conocido como “Uncle Bob” que se basa en la premisa de estructurar el código en capas contiguas, es decir, que solo tienen comunicación con las capas que están inmediatamente a sus lados. Basados en esta idea podemos encontrar artículos que hablan sobre Clean Architecture, Onion Architecture, Hexagonal Architecture, todas ellas tienen diferentes enfoques, pero comparten la idea de que cada nivel debe realizar sus propias tareas y se comunica únicamente con sus niveles inmediatamente contiguos.

Los niveles de los que se compone Clean Architecture son los siguientes:

UI: la interfaz de usuario propiamente dicha (html, xml, etc).

Presenters: clases que se subscriben a los eventos generados por la interfaz y que responden en consecuencia, también realizan el pintado de la información en la interfaz.

Use Cases: evaluación de reglas de negocio y tomas de decisiones.

Entities: modelo de datos de la aplicación, comunicación con servicios web, cache de datos.

Este es el gráfico original que propone Uncle Bob y se puede apreciar como los diferentes niveles anteriormente descritos sólo se comunican con los inmediatamente contiguos.

Deloitte

A continuación, tenemos otra interpretación del gráfico tradicional, en la que se han añadido descripción de las tareas que se suelen realizar en cada uno de los niveles. 

Deloitte

Cada uno de los niveles aquí representados podría considerarse dentro de la estructura de nuestra aplicación como carpetas independientes, diferentes módulos o librerías que se incluyen como dependencias del proyecto principal o incluso podríamos aplicar este tipo de estructuración sin la necesidad de reflejarlo de forma explícita en la estructura del proyecto.          

Ahora que conocemos los fundamentos básicos de Clean Architecture, vamos a ver cuáles son algunas de las ventajas e inconvenientes a las que nos enfrentaremos si decidimos aplicar esta metodología de trabajo en nuestro proyecto.

Ventajas

 
  • Independencia: cada capa tiene su propio paradigma o modelo arquitectónico como si se tratara de una aplicación en si misma sin afectar al resto de los niveles.
  • Estructuración: mejor organización del código, facilitando la búsqueda de funcionalidades y navegación por el mismo.
  • Desacoplamiento: cada capa es independiente de las demás por lo que podríamos reemplazarla o incluso desarrollar en diferentes tecnologías. Además de reutilizar alguna de ellas en diferentes proyectos.
  • Facilidad de testeo: podremos realizar test unitarios de cada una de las capas y test de integración de las diferentes capas entre sí, pudiendo reemplazarlas por objectos temporales que simulen su comportamiento de forma sencilla.

Desventajas

 

Metodología: todo el equipo de desarrollo debe conocer la metodología que se está aplicando y cada desarrollador debe ser responsable de entender y aplicar las reglas establecidas a medida que está desarrollando.

Complejidad: la velocidad de desarrollo al comienzo del proyecto es menor debido a que hay que establecer esta estructura y todo el equipo debe adaptarse a la nueva forma de trabajar, pero poco a poco y a medida que la aplicación va creciendo el mantenimiento y ampliación será más sencillo.

Conclusiones

 

En mis años de experiencia como desarrollador, he probado diferentes aproximaciones a la hora de comenzar un nuevo proyecto. La premisa que he intentado mantener como base es proporcionar al proyecto unos cimientos que ayuden al crecimiento y desarrollo del mismo. Para ello, últimamente he aplicado estos principios y puedo garantizar que la escalabilidad y mantenibilidad del código es mucho mayor, pudiendo invertir menos tiempo en desarrollar nuevas funcionalidades o ampliar las ya existentes.

Clean Architecture proporciona ideas sobre cómo organizar nuestro código en diferentes niveles. Pero la manera en la que estos se comunican entre sí, la organización interna de cada uno de ellos y la creación del árbol de directorios del proyecto, son algunas de las preguntas abiertas que quedan en este artículo. Como he podido comprobar, durante el tiempo que he estado usando Clean, se pueden realizar diferentes combinaciones, todas y cada una de ellas válidas, para adaptarse a las necesidades del proyecto o incluso a las preferencias de los integrantes del equipo de desarrollo.

Pero para mí lo más importante es la idea de que cada clase que tenemos dentro de un proyecto tiene que cubrir únicamente el rol para el que ha sido creada y no abarcar más funcionalidades de las que debe, ya que esto generará dificultades futuras. Si tenemos clara esta idea, la aplicación de Clean será una progresión lógica en nuestra vida como desarrollador para mejorar la calidad de nuestros productos.

Abimael Barea

 

Abimael es analista senior con experiencia en desarrollo de aplicaciones móviles. Ha trabajado con tecnologías nativas e híbridas como Java, Kotlin, Objective-C, Swift, Angular (Typescript).
También con metodologías ágiles como SCRUM, realizada estimaciones, gestión de git, integración continua (Jenkins, Lint, SonarQube). Por otro lado ha formado parte de evaluaciones de usabilidad de aplicaciones y del proceso de diseño de las mismas.