La arquitectura en capas es, probablemente, el estilo arquitectónico más extendido del mundo. Casi cualquier aplicación empresarial que hayas usado —un banco, una tienda online, un gestor de pólizas— está organizada internamente en capas: una para la presentación, otra para las reglas de negocio y otra para hablar con la base de datos. Su éxito se debe a que es intuitiva, fácil de enseñar y proporciona una separación de responsabilidades clara. Sin embargo, aplicada sin criterio, esconde trampas como las capas que no aportan nada (el "antipatrón sumidero") o el acoplamiento entre niveles. En esta lección entenderemos las capas habituales, la diferencia entre capas abiertas y cerradas, y los errores que conviene evitar.

Contenido

  1. Qué es la arquitectura en capas
  2. Las capas habituales: presentación, negocio y persistencia
  3. Capas cerradas vs capas abiertas
  4. Ventajas e inconvenientes
  5. El antipatrón de la capa sumidero
  6. Ejemplo práctico end-to-end
  7. Errores comunes y consejos
  8. Ejercicios
  9. Conclusión

  1. Qué es la arquitectura en capas

La arquitectura en capas (también llamada N-Tier o layered architecture) organiza el software en grupos horizontales de responsabilidad. Cada capa:

  • Tiene una responsabilidad bien definida.
  • Solo se comunica con la capa inmediatamente inferior (en su forma cerrada).
  • Oculta sus detalles internos a las capas superiores.
graph TD
    P[Capa de Presentación\nControladores, vistas, DTOs]
    N[Capa de Negocio\nServicios, reglas, casos de uso]
    PE[Capa de Persistencia\nRepositorios, DAOs]
    BD[(Base de Datos)]
    P --> N --> PE --> BD

Conviene aclarar una confusión habitual de vocabulario:

  • Layer (capa lógica): una división del código por responsabilidad. Varias capas pueden vivir en el mismo proceso.
  • Tier (nivel físico): una división del despliegue (máquinas/procesos distintos). El navegador, el servidor de aplicaciones y el servidor de BD son tres tiers.

Un monolito puede tener 3 layers y desplegarse en 1 solo tier. Son ejes independientes.

  1. Las capas habituales: presentación, negocio y persistencia

Capa Responsabilidad Qué SÍ contiene Qué NO debe contener
Presentación Interactuar con el exterior Controladores REST, mapeo de DTOs, validación de formato Reglas de negocio, SQL
Negocio Reglas y casos de uso Servicios, validaciones de negocio, orquestación de transacciones HTML, SQL crudo, detalles HTTP
Persistencia Acceso a datos Repositorios, DAOs, mapeo objeto-relacional Reglas de negocio, lógica de presentación

La idea central: cada concepto vive en una sola capa. Si una regla de negocio aparece en un controlador o en una consulta SQL, se ha roto la separación.

// Capa de Presentación: solo traduce HTTP <-> modelo
@RestController
@RequestMapping("/polizas")
class PolizaController {

    private final ServicioPolizas servicio; // depende de la capa de negocio

    PolizaController(ServicioPolizas servicio) { this.servicio = servicio; }

    @PostMapping
    PolizaResponse crear(@RequestBody @Valid PolizaRequest req) {
        // 1) Traduce el DTO de entrada a una orden de negocio
        var id = servicio.contratar(req.toComando());
        // 2) Traduce el resultado a un DTO de salida
        return new PolizaResponse(id);
    }
}

Explicación:

  • El controlador no toma decisiones de negocio: valida el formato de la petición (@Valid), traduce a un comando y delega en ServicioPolizas.
  • Devuelve un DTO de respuesta propio de la capa de presentación, sin filtrar entidades internas.

  1. Capas cerradas vs capas abiertas

Esta es una de las decisiones más importantes —y peor entendidas— del estilo en capas.

  • Capa cerrada: una petición que la atraviesa no puede saltársela. Para llegar de Presentación a Persistencia, debe pasar por Negocio.
  • Capa abierta: una petición puede saltársela y acceder directamente a la capa inferior.
graph TD
    subgraph Cerrada
        A1[Presentación] --> A2[Negocio] --> A3[Persistencia]
    end
    subgraph Con capa abierta
        B1[Presentación] --> B2[Negocio]
        B2 --> B3[Servicios compartidos\nCAPA ABIERTA]
        B3 --> B4[Persistencia]
        B2 -.salta.-> B4
    end
Aspecto Capas cerradas Capas abiertas
Aislamiento entre capas Máximo Menor
Coste de un cambio Localizado Puede propagarse
Riesgo de saltos descontrolados Bajo Alto si se abusa
Uso típico Por defecto, recomendado Capas de servicios compartidos/utilidades

Recomendación: mantén las capas cerradas por defecto. Solo abre una capa cuando exista una razón fuerte (por ejemplo, una capa transversal de utilidades) y documéntalo. Las capas cerradas dan aislamiento de cambios: si modificas la persistencia, solo la capa de negocio puede verse afectada.

  1. Ventajas e inconvenientes

Ventajas Inconvenientes
Separación de responsabilidades clara y fácil de enseñar Puede degenerar en muchas capas que no aportan valor
Sustituibilidad: cambiar la BD afecta solo a persistencia Riesgo de capa sumidero (ver apartado 5)
Pruebas por capa con dependencias simuladas El acoplamiento vertical sigue existiendo
Encaja de forma natural en cualquier framework MVC Las reglas tienden a "filtrarse" a presentación o persistencia
Bajo coste de entrada para equipos El dominio queda subordinado a la infraestructura (la BD suele "mandar")

Un matiz importante respecto a estilos posteriores (hexagonal, clean): en la arquitectura en capas el dominio depende hacia abajo de la persistencia. Eso significa que la base de datos tiende a condicionar el modelo de negocio. Lo veremos resuelto en lecciones posteriores con la inversión de dependencias.

  1. El antipatrón de la capa sumidero

El antipatrón de la capa sumidero (architecture sinkhole anti-pattern) ocurre cuando muchas peticiones atraviesan las capas sin que estas hagan nada útil: simplemente delegan a la capa inferior. La capa se convierte en un "sumidero" que añade código y latencia sin aportar valor.

// SÍNTOMA: la capa de negocio no hace nada, solo reenvía
class ServicioClienteSumidero {
    private final RepositorioCliente repo;
    ServicioClienteSumidero(RepositorioCliente repo) { this.repo = repo; }

    // Pass-through puro: sin reglas, sin validación, sin orquestación
    Cliente buscar(Long id) {
        return repo.buscar(id); // ¿para qué existe esta capa entonces?
    }
}

¿Por qué es un problema y cuándo NO lo es?

  • Es un problema si la mayoría de las operaciones del sistema son meros pass-through: estás pagando el coste de la capa sin obtener su beneficio.
  • NO es un problema si solo algunas operaciones son simples mientras otras sí contienen reglas. La regla heurística habitual es la 80/20: si el 80% de las peticiones pasan de largo, replantea las capas; si solo el 20%, es aceptable mantener la uniformidad.

Posibles soluciones:

  • Abrir capas concretas para que ciertas peticiones simples salten directamente (con criterio).
  • Para consultas de solo lectura, usar un patrón CQRS ligero que lea directamente del modelo de lectura.

  1. Ejemplo práctico end-to-end

Veamos las tres capas colaborando para contratar una póliza, con la regla de negocio en su sitio.

// --- Capa de Negocio ---
class ServicioPolizas {
    private final RepositorioPolizas repo;
    private final TarificadorRiesgo tarificador;

    ServicioPolizas(RepositorioPolizas repo, TarificadorRiesgo t) {
        this.repo = repo; this.tarificador = t;
    }

    Long contratar(ComandoContratar cmd) {
        // Regla de negocio real: rechazar riesgos no asegurables
        if (!tarificador.esAsegurable(cmd.riesgo())) {
            throw new RiesgoNoAsegurableException(cmd.riesgo());
        }
        var prima = tarificador.calcularPrima(cmd.riesgo());
        var poliza = new Poliza(cmd.cliente(), cmd.riesgo(), prima);
        return repo.guardar(poliza); // delega persistencia
    }
}

// --- Capa de Persistencia ---
interface RepositorioPolizas {
    Long guardar(Poliza poliza);
}

Explicación detallada:

  • ServicioPolizas (negocio) contiene una decisión real: comprueba si el riesgo es asegurable y calcula la prima. No es un sumidero.
  • RepositorioPolizas (persistencia) se define como interfaz: la capa de negocio depende de un contrato, no de una implementación JPA o JDBC concreta. Esto facilita las pruebas con un repositorio falso.
  • El flujo completo es: PolizaController (presentación) → ServicioPolizas (negocio) → RepositorioPolizas (persistencia) → BD. Capas cerradas, sin saltos.
-- La tabla que respalda la persistencia (detalle de la capa inferior)
CREATE TABLE polizas (
    id        BIGINT PRIMARY KEY AUTO_INCREMENT,
    cliente   VARCHAR(120) NOT NULL,
    riesgo    VARCHAR(60)  NOT NULL,
    prima     DECIMAL(10,2) NOT NULL
);

Observa que el SQL solo aparece en la capa de persistencia. Ni el controlador ni el servicio saben que detrás hay una tabla relacional.

  1. Errores Comunes y Consejos

  • Filtrar reglas de negocio a la presentación. Si un if decide algo del dominio dentro de un controlador, muévelo al servicio.
  • Devolver entidades de persistencia al exterior. Expón DTOs; no filtres tu modelo interno por la API.
  • Crear capas vacías "por simetría". No añadas una capa de servicio si no hace nada; eso es exactamente la capa sumidero.
  • Abrir todas las capas "por flexibilidad". Cierra por defecto; abre solo con justificación.
  • Confundir capa (layer) con nivel (tier). Decidir cuántos layers tienes es independiente de en cuántas máquinas despliegas.
  • Consejo: numera tus capas mentalmente y, ante cada clase, pregúntate "¿en qué capa vive esta responsabilidad?". Si no lo tienes claro, probablemente la clase hace demasiado.

  1. Ejercicios

Ejercicio 1. Clasifica cada elemento en su capa (Presentación, Negocio o Persistencia): (a) @RestController que recibe JSON. (b) Cálculo del recargo por impago. (c) Mapeo de una entidad a su tabla con JPA. (d) Validación @NotNull del formato de un campo de entrada.

Ejercicio 2. Tu jefe propone abrir todas las capas "para ir más rápido". Da dos argumentos en contra y explica en qué caso concreto sí abrirías una.

Ejercicio 3. Detecta si este servicio es un antipatrón sumidero y propón una mejora:

class ServicioPedidos {
    private final RepositorioPedidos repo;
    Pedido obtener(Long id) { return repo.buscar(id); }
    List<Pedido> listar()    { return repo.listarTodos(); }
}

Soluciones

Solución 1. (a) Presentación. (b) Negocio. (c) Persistencia. (d) Presentación (validación de formato; las validaciones de negocio irían en la capa de negocio).

Solución 2. Argumentos en contra: (1) se pierde el aislamiento de cambios, ya que la presentación podría acoplarse directamente a la persistencia; (2) se fomenta saltarse las reglas de negocio, dispersándolas. Caso en que sí abriría: una capa transversal de utilidades/servicios compartidos (logging, traducción de mensajes) que no encierra reglas de dominio.

Solución 3. Es un antipatrón sumidero: ambos métodos son pass-through puros sin reglas. Mejora posible: para estas lecturas simples, aplicar CQRS ligero y dejar que la presentación consulte un modelo de lectura directamente, reservando la capa de negocio para operaciones que sí contengan reglas (crear/modificar pedidos con validaciones).

  1. Conclusión

La arquitectura en capas es el estilo de organización interna por excelencia: separa presentación, negocio y persistencia, y aporta una separación de responsabilidades clara y fácil de adoptar. Hemos visto la diferencia entre capas cerradas y abiertas, sus ventajas e inconvenientes, y el peligroso antipatrón de la capa sumidero. Su gran limitación —que el dominio depende hacia abajo de la infraestructura— será precisamente lo que resolverán estilos posteriores. Antes de llegar ahí, en la próxima lección estudiaremos cómo se reparten estas capas entre máquinas distintas con la Arquitectura Cliente-Servidor, donde el eje pasa de lo lógico (layers) a lo físico (tiers).

Curso de Arquitectura de Aplicaciones

Módulo 1: Fundamentos de la Arquitectura de Aplicaciones

Módulo 2: Principios y Tácticas de Diseño

Módulo 3: Estilos y Patrones Arquitectónicos

Módulo 4: Arquitecturas Distribuidas y Microservicios

Módulo 5: Arquitecturas Dirigidas por Eventos y Mensajería

Módulo 6: Diseño Dirigido por el Dominio (DDD)

Módulo 7: Datos y Persistencia

Módulo 8: Arquitectura en la Nube y Despliegue

Módulo 9: Calidad, Seguridad y Observabilidad

Módulo 10: Evolución, Gobernanza y Casos Prácticos

© Copyright 2026. Todos los derechos reservados