Why this matters
When a service directly imports a database driver or fires raw SQL, the business rule and the storage plumbing are fused. You can't test the rule without a real database, you can't swap Postgres for Redis without rewriting the service, and every storage detail bleeds into the domain. The Repository pattern draws a clean line: define an interface that describes what the domain needs (find pending orders, save an order), then provide separate implementations for production storage and in-memory testing. The domain never imports a driver again.
Cuando un servicio importa directamente un driver de base de datos o ejecuta SQL en bruto, la regla de negocio y la fontanería de almacenamiento están fusionadas. No puedes probar la regla sin una base de datos real, no puedes cambiar Postgres por Redis sin reescribir el servicio, y cada detalle de almacenamiento se filtra al dominio. El patrón Repository traza una línea limpia: define una interfaz que describe qué necesita el dominio (encontrar pedidos pendientes, guardar un pedido), y luego proporciona implementaciones separadas para almacenamiento en producción y pruebas en memoria. El dominio nunca vuelve a importar un driver.
Testing becomes trivial
Las pruebas se vuelven triviales
With a repository interface in place, a complete unit test for OrderService needs no database, no network, no docker-compose. Inject an InMemoryOrderRepository, seed it with test data, and verify results — the test runs in milliseconds and never flakes. In production, inject PostgresOrderRepository via your DI container. Same service, zero changes.
Con una interfaz de repositorio en su lugar, una prueba unitaria completa para OrderService no necesita base de datos, ni red, ni docker-compose. Inyecta un InMemoryOrderRepository, siémbralo con datos de prueba y verifica los resultados — la prueba se ejecuta en milisegundos y nunca falla por razones externas. En producción, inyecta PostgresOrderRepository a través de tu contenedor DI. El mismo servicio, cero cambios.
💡 Key takeaway
Repository hides the plumbing. Your domain speaks to an interface — swapping Postgres for in-memory, Redis, or a remote API is a one-liner in the DI wiring, not a rewrite of business logic.
Repository oculta la fontanería. Tu dominio habla con una interfaz — cambiar Postgres por in-memory, Redis o una API remota es una línea en el cableado DI, no una reescritura de la lógica de negocio.