Este repositorio es una aplicación de ejemplo que demuestra los principios SOLID aplicados en una API REST construida con Java 17, Spring Boot y Maven. Cada paquete dentro de src/main/java/cl/edu/dev/solid contiene una pequeña muestra enfocada en uno de los principios SOLID.
- Servir como referencia didáctica para entender cómo estructurar código siguiendo SOLID.
- Proveer endpoints simples para ver ejemplos prácticos (servicios, controladores, modelos e inyección de dependencias).
- Java 17
- Spring Boot
- Maven (incluye
mvnw/mvnw.cmd) - Lombok (para reducir boilerplate en modelos)
- H2 (mencionado como opción para demos; proyecto usa JPA en
User)
-
src/main/java/cl/edu/dev/solid/srp- Ejemplo SRP (Single Responsibility Principle)controller/UserController.java- Endpoints para usuariosservice/UserService.java- Lógica de negociorepository/UserRepository.java- Persistenciamodel/User.java- Entidad JPA
-
src/main/java/cl/edu/dev/solid/ocp- Ejemplo OCP (Open/Closed Principle)model/Shape,Circle,Rectangle- Interfaz y implementacionesservice/ShapeService.java- Cálculo de áreas (cerrado para modificación, abierto a nuevas formas)controller/ShapeController.java- Endpoint para calcular áreas
-
src/main/java/cl/edu/dev/solid/lsp- Ejemplo LSP (Liskov Substitution Principle)model/Bird,FlyingBird,Penguin-Penguinlanza excepción al volarservice/BirdService.java- Maneja colección de avescontroller/BirdController.java- Endpoint para listar aves
-
src/main/java/cl/edu/dev/solid/isp- Ejemplo ISP (Interface Segregation Principle)interfaces/Worker,Eatery modelosHuman,Robotcontroller/WorkerController.java- Endpoints demostrativos
-
src/main/java/cl/edu/dev/solid/dip- Ejemplo DIP (Dependency Inversion Principle)interfaces/MessageSendery componentesEmailSender,SMSSenderservice/NotificationService.java- Inyecta abstraccionescontroller/NotificationController.java- Endpoints para enviar notificaciones
Nota: documentado tal como está en el código fuente.
-
Usuarios (SRP)
- GET /users -> Devuelve lista de usuarios (JSON)
- POST /users -> Crea un nuevo usuario (cuerpo JSON con { "name": "...", "email": "..." })
-
Notificaciones (DIP)
- POST /notifications/email?message=hola -> Envía un email (retorna texto de confirmación)
- POST /notifications/sms?message=hola -> Envía un SMS (retorna texto de confirmación)
-
Trabajadores (ISP)
- GET /workers/human -> Demostración:
human.work()+human.eat() - GET /workers/robot -> Demostración:
robot.work()(noeat)
- GET /workers/human -> Demostración:
-
Aves (LSP)
- GET /birds -> Devuelve la lista interna de aves (la gestión de altas/bajas está en el servicio)
-
Formas / Áreas (OCP)
- GET /shapes/areas -> Calcula área total a partir de una lista de
Shapeen el cuerpo de la petición- Observación: el controlador usa
@GetMappingcon@RequestBody, lo habitual sería usarPOSTpara peticiones con cuerpo. Está documentado tal cual en el código.
- Observación: el controlador usa
- GET /shapes/areas -> Calcula área total a partir de una lista de
Iniciar la aplicación (Windows, usa el wrapper):
# Compilar y ejecutar con el wrapper (Windows)
./mvnw.cmd spring-boot:runEjemplos de llamadas a la API (PowerShell):
# Obtener usuarios
curl http://localhost:8080/users
# Crear usuario (JSON)
curl -H "Content-Type: application/json" -X POST -d '{"name":"Juan","email":"juan@example.com"}' http://localhost:8080/users
# Enviar notificación por email
curl -X POST "http://localhost:8080/notifications/email?message=Hola%20mundo"
# Enviar SMS
curl -X POST "http://localhost:8080/notifications/sms?message=Hola%20mundo"
# Llamada a shapes/areas (ejemplo JSON; el endpoint espera un cuerpo con la lista de shapes)
# Nota: como las clases Shape/Circle/Rectangle en Java no se deserializarán automáticamente sin DTOs/serializadores, este endpoint sirve como demostración de OCP en código, y podría necesitar adaptaciones para recibir JSON reales.Para ejecutar tests (si existen) y comprobar el build:
./mvnw.cmd testUserestá marcada con@Entityy usa Lombok (@Data), pero los campos no tienen anotaciones JPA como@Id; si deseas persistencia real debes añadir@Idy estrategia de generación.ShapeControllerusa@GetMappingcon@RequestBody; lo correcto sería@PostMappingo cambiar a recibir parámetros por query.BirdServiceexpone métodos para agregar y manipular aves, pero elBirdControlleractual solo ofreceGET /birds. Si deseas endpoints para añadir o eliminar aves, se puede ampliar el controlador.Penguin#fly()lanzaUnsupportedOperationExceptiona propósito para ilustrar violaciones potenciales de LSP; el servicio captura esa excepción cuando intenta hacer volar a todas las aves.
- Añade endpoints faltantes para operaciones CRUD si deseas practicar (por ejemplo, agregar/eliminar aves, endpoints para
Shapeque acepten DTOs, o completar la entidadUsercon@Id). - Mantén las responsabilidades separadas: controladores para entrada/salida, servicios para lógica, repositorios para persistencia.
- README actualizado con descripción, estructura, endpoints, comandos de ejecución y ejemplos: Hecho
- Notas sobre inconsistencias y cómo mejorarlas: Incluidas
Proyecto de ejemplo — úsalo como guía. Para dudas o mejoras, abre issues o solicita cambios.