En el desarrollo de software, mantener la escalabilidad y la organización del código es crucial para el éxito a largo plazo. Clean Architecture, propuesta por Robert C. Martin, es una metodología que ayuda a lograr estos objetivos al separar las responsabilidades del código en capas bien definidas. En este artículo, vamos a conocer los fundamentos básicos sobre la Clean Architecture con Spring Boot y Node.js. Leer documentación aquí
Construyendo un Imperio Digital con Clean Architecture
Por ejemplo, imaginemos que estamos construyendo un castillo medieval. No podemos simplemente amontonar piedras al azar y esperar que se mantenga en pie. Necesitamos una estructura sólida, una base firme sobre la que construir. En el mundo del desarrollo de software, esa estructura es la Arquitectura Limpia.
¿Qué es la Arquitectura Limpia?
Es un conjunto de principios de diseño que buscan separar las preocupaciones de un sistema de software, haciendo que sea más fácil de entender, mantener y evolucionar. Es como construir un castillo con una muralla exterior que protege la fortaleza interior.
Principios de Clean Architecture
Se basa en varios principios clave:
- Independencia de Frameworks: El sistema no debe depender de frameworks específicos.
- Testabilidad: El código debe ser fácil de probar.
- Independencia de la UI: La interfaz de usuario puede cambiar sin afectar el resto del sistema.
- Independencia de la Base de Datos: La lógica de negocio no debe depender de la base de datos.
- Independencia de Agentes Externos: Los detalles de implementación pueden cambiar sin afectar la lógica de negocio.
Estructura de Clean Architecture
Se organiza en capas concéntricas, donde cada capa tiene una responsabilidad específica:
- Entidades: Contienen las reglas de negocio más generales.
- Casos de Uso: Contienen la lógica de aplicación específica.
- Interfaces de Adaptadores: Contienen la lógica de presentación y los adaptadores para interactuar con la infraestructura.
- Frameworks y Drivers: Contienen los detalles de implementación, como frameworks y bases de datos.
Clean Architecture: Spring Boot y Node.js
Ahora, imagina que tu aplicación es el castillo medieval, en donde cada capa de Clean Architecture representa una parte del castillo, con sus propias responsabilidades y protecciones.
Spring Boot
Una aplicación de comercio electrónico podría tener entidades como “Producto” y “Cliente”, casos de uso como “Agregar al carrito” y “Realizar pedido”, y repositorios para interactuar con la base de datos. Ahora, veamos un ejemplo de cómo aplicar Clean Architecture en un proyecto de Spring Boot.
- Entidades (El Núcleo del Castillo): Las entidades son las reglas de negocio más generales y fundamentales. Son como el núcleo del castillo, donde se guardan los tesoros más valiosos y protegidos.
// Entidad de Usuario en Spring Boot
public class User {
private Long id;
private String name;
private String email;
// Getters y Setters
}
Lenguaje del código: PHP (php)
- Casos de Uso (La Sala del Trono): Los casos de uso contienen la lógica de aplicación específica. Son como la sala del trono, donde se toman las decisiones importantes y se ejecutan las órdenes.
// Caso de Uso para Crear Usuario en Spring Boot
public class CreateUserUseCase {
private final UserRepository userRepository;
public CreateUserUseCase(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void execute(User user) {
userRepository.save(user);
}
}
Lenguaje del código: PHP (php)
- Interfaces de Adaptadores (Las Murallas del Castillo): Las interfaces de adaptadores contienen la lógica de presentación y los adaptadores para interactuar con la infraestructura. Son como las murallas del castillo, protegiendo el núcleo y facilitando la interacción con el exterior.
// Controlador REST en Spring Boot
@RestController
@RequestMapping("/users")
public class UserController {
private final CreateUserUseCase createUserUseCase;
public UserController(CreateUserUseCase createUserUseCase) {
this.createUserUseCase = createUserUseCase;
}
@PostMapping
public ResponseEntity<Void> createUser(@RequestBody User user) {
createUserUseCase.execute(user);
return ResponseEntity.status(HttpStatus.CREATED).build();
}
}
Lenguaje del código: PHP (php)
- Frameworks y Drivers (El Foso y el Puente Levadizo): Los frameworks y drivers contienen los detalles de implementación, como frameworks y bases de datos. Son como el foso y el puente levadizo, proporcionando una capa adicional de protección y facilitando el acceso controlado al castillo.
// Repositorio de Usuario en Spring Boot
@Repository
public class UserRepositoryImpl implements UserRepository {
private final JpaUserRepository jpaUserRepository;
public UserRepositoryImpl(JpaUserRepository jpaUserRepository) {
this.jpaUserRepository = jpaUserRepository;
}
@Override
public void save(User user) {
jpaUserRepository.save(user);
}
}
Lenguaje del código: PHP (php)
Node.js
- Frameworks: Express.js y NestJS son excelentes opciones para implementar arquitecturas limpias en Node.js.
- Patrones: Utiliza patrones de diseño como Repository, Service, Controller para separar las responsabilidades.
- TypeScript: Agrega tipado estático a tu código JavaScript para mejorar la legibilidad y reducir errores.
Ahora, con un ejemplo sencillo veamos cómo aplicar Clean Architecture en un proyecto de Node.js.
- Entidades:
// Entidad de Usuario en Node.js
class User {
constructor(id, name, email) {
this.id = id;
this.name = name;
this.email = email;
}
}
module.exports = User;
Lenguaje del código: JavaScript (javascript)
- Casos de Uso:
// Caso de Uso para Crear Usuario en Node.js
class CreateUserUseCase {
constructor(userRepository) {
this.userRepository = userRepository;
}
execute(user) {
return this.userRepository.save(user);
}
}
module.exports = CreateUserUseCase;
Lenguaje del código: JavaScript (javascript)
- Interfaces de Adaptadores:
// Controlador REST en Node.js
const express = require('express');
const router = express.Router();
const CreateUserUseCase = require('../use_cases/CreateUserUseCase');
const UserRepository = require('../repositories/UserRepository');
const userRepository = new UserRepository();
const createUserUseCase = new CreateUserUseCase(userRepository);
router.post('/users', (req, res) => {
const user = req.body;
createUserUseCase.execute(user)
.then(() => res.status(201).send())
.catch(err => res.status(500).send(err.message));
});
module.exports = router;
Lenguaje del código: JavaScript (javascript)
- Frameworks y Drivers:
// Repositorio de Usuario en Node.js
class UserRepository {
constructor() {
this.users = [];
}
save(user) {
this.users.push(user);
return Promise.resolve();
}
}
module.exports = UserRepository;
Lenguaje del código: JavaScript (javascript)
¿Por qué es importante?
- Escalabilidad: A medida que tu proyecto crece, una arquitectura limpia te permite agregar nuevas funcionalidades sin afectar el resto del sistema.
- Mantenibilidad: Un código bien estructurado es más fácil de entender y modificar.
- Testabilidad: Una arquitectura limpia facilita la escritura de pruebas unitarias y de integración.
- Reutilización: Los componentes de un sistema bien diseñado pueden ser reutilizados en otros proyectos.
Consejos para Implementar Clean Architecture
- Comienza con una Base Sólida: Define claramente las entidades y casos de uso antes de implementar los detalles de infraestructura, es decir, empieza por el dominio.
- Mantén la Simplicidad: No compliques demasiado la arquitectura. Mantén las capas bien definidas y separadas, en otras palabras, separa las preocupaciones, porque cada capa debe tener una responsabilidad específica.
- Prueba tu Código: Asegúrate de que cada capa sea fácilmente testeable, realiza pruebas unitarias para asegurarte de que cada componente de tu sistema funcione correctamente de forma aislada.
- Refactoriza Regularmente: A medida que el proyecto crece y evoluciona, refactoriza el código para mantener la organización y la escalabilidad.
- Utiliza patrones de diseño: Patrones como Dependency Injection y SOLID te ayudarán a construir un código más limpio y mantenible.
La Arquitectura Limpia no es una receta mágica, pero es una guía invaluable para construir sistemas de software de alta calidad. Al igual que un castillo bien construido puede resistir el paso del tiempo, un software bien diseñado puede adaptarse a los cambios y crecer contigo.
Aplicar Clean Architecture en nuestros proyectos puede ayudarnos a mantener la escalabilidad y la organización del código, evitando el caos a medida que el proyecto crece. Ya sea que trabajemos con Spring Boot o Node.js, estos principios nos permitirán construir aplicaciones robustas y mantenibles.