¡Entendido! Aquí tienes el contenido listo para copiar y pegar. He elegido el lenguaje Golang (Go) porque es el estándar actual para desarrollo backend empresarial de alto rendimiento y se ajusta perfectamente a los patrones de arquitectura limpia.
El patrón elegido es el Repository Pattern (Patrón Repositorio), uno de los más fundamentales del libro de Martin Fowler para desacoplar la lógica de negocio de la base de datos.
Parte 1: El Artículo (Para Dev.To / Medium / HashNode)
Título: 🏛️ Enterprise Patterns en Golang: Desacoplando tu código con el Patrón Repositorio
Subtítulo: Cómo aplicar las enseñanzas de Martin Fowler en el desarrollo moderno de microservicios con Go.
Tags: #Golang #SoftwareArchitecture #DesignPatterns #Backend #CleanCode
Introducción: El problema del acoplamiento
Cuando leemos "Patterns of Enterprise Application Architecture" de Martin Fowler, a veces pensamos en sistemas monolíticos antiguos de Java. Sin embargo, estos patrones son más relevantes que nunca en la era de los microservicios.
Un error común en aplicaciones Go es mezclar las consultas SQL (SELECT * FROM...) directamente dentro de los controladores HTTP o la lógica de negocio. Esto hace que el código sea imposible de testear y difícil de migrar.
Hoy implementaremos el Repository Pattern. Este patrón crea una capa de abstracción entre el dominio (tu lógica) y el mapeo de datos (tu base de datos), permitiendo que tu aplicación evolucione sin romper el núcleo del negocio.
El Escenario
Imaginemos un sistema empresarial de gestión de empleados. Necesitamos crear un empleado y guardarlo. No nos importa si se guarda en Postgres, MySQL o en Memoria; nuestra lógica de negocio no debería saberlo.
La Implementación en Go
Primero, definimos nuestra Entidad (El Dominio).
// domain/employee.go
package domain
type Employee struct {
ID string
Name string
Role string
Salary float64
}
Ahora, la clave del patrón: La Interfaz del Repositorio. Esto es el contrato que define qué necesitamos, sin decir cómo se hace.
// domain/repository.go
package domain
// EmployeeRepository define el contrato para acceder a los datos
type EmployeeRepository interface {
Save(employee *Employee) error
FindByID(id string) (*Employee, error)
}
Implementamos la lógica de negocio (Service Layer). Fíjate cómo el servicio pide un EmployeeRepository en su constructor. Esto es Inyección de Dependencias.
// service/employee_service.go
package service
import (
"errors"
"enterprise-patterns/domain"
)
type EmployeeService struct {
repo domain.EmployeeRepository
}
func NewEmployeeService(repo domain.EmployeeRepository) *EmployeeService {
return &EmployeeService{repo: repo}
}
func (s *EmployeeService) RegisterEmployee(id, name, role string) error {
if name == "" {
return errors.New("el nombre no puede estar vacío")
}
// Lógica de negocio: Regla empresarial
// "Solo los gerentes pueden tener bonos iniciales (simulado aquí)"
emp := &domain.Employee{
ID: id,
Name: name,
Role: role,
}
return s.repo.Save(emp)
}
Finalmente, la implementación concreta (La infraestructura). Aquí es donde iría SQL, pero usaremos un mapa en memoria para el demo.
// infrastructure/memory_repo.go
package infrastructure
import (
"errors"
"enterprise-patterns/domain"
)
type InMemoryEmployeeRepo struct {
store map[string]*domain.Employee
}
func NewInMemoryRepo() *InMemoryEmployeeRepo {
return &InMemoryEmployeeRepo{
store: make(map[string]*domain.Employee),
}
}
func (r *InMemoryEmployeeRepo) Save(employee *domain.Employee) error {
if _, exists := r.store[employee.ID]; exists {
return errors.New("el empleado ya existe")
}
r.store[employee.ID] = employee
return nil
}
func (r *InMemoryEmployeeRepo) FindByID(id string) (*domain.Employee, error) {
if emp, ok := r.store[id]; ok {
return emp, nil
}
return nil, errors.New("empleado no encontrado")
}
Uso en el main.go
Así es como unimos todo:
// main.go
package main
import (
"fmt"
"enterprise-patterns/infrastructure"
"enterprise-patterns/service"
)
func main() {
// 1. Crear la implementación concreta (Infraestructura)
repo := infrastructure.NewInMemoryRepo()
// 2. Inyectar el repositorio en el servicio (Dominio)
empService := service.NewEmployeeService(repo)
// 3. Ejecutar la lógica
err := empService.RegisterEmployee("001", "Carlos Dev", "Senior Engineer")
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Empleado registrado exitosamente usando Repository Pattern!")
}
}
Conclusión
Al usar el Repository Pattern, hemos logrado que nuestro EmployeeService sea 100% agnóstico de la base de datos. Si mañana queremos cambiar de memoria a MongoDB, solo creamos un nuevo archivo en infrastructure y no tocamos ni una línea de la lógica de negocio. Eso es arquitectura empresarial robusta.

Top comments (0)