Estructuras de carpetas, arquitecturas y patrones de diseño en Go (Golang), incluyendo manejo de concurrencia
1. Estructuras de Carpetas en Go
1.1 Estructura Básica
project/
├── cmd/
│ └── app/
│ └── main.go
├── internal/
│ ├── handler/
│ ├── service/
│ └── repository/
├── pkg/
│ ├── utils/
│ └── logger/
├── api/
├── configs/
├── test/
├── scripts/
├── deployments/
├── go.mod
└── go.sum
1.2 Clean Architecture
project/
├── cmd/
├── internal/
│ ├── entity/ # Entidades de negocio
│ ├── usecase/ # Lógica de negocio
│ ├── repository/ # Interfaces de repositorio
│ └── delivery/ # Controladores (HTTP, gRPC, CLI)
├── pkg/
├── infrastructure/ # Implementaciones concretas
│ ├── db/
│ ├── cache/
│ └── web/
└── ...
1.3 Arquitectura Hexagonal
project/
├── core/ # Lógica de negocio
├── ports/ # Interfaces
├── adapters/ # Implementaciones
│ ├── primary/ # Controladores
│ └── secondary/ # Bases de datos, APIs externas
└── ...
2. Arquitecturas Principales
2.1 MVC (Model-View-Controller)
// Model
type User struct {
ID int
Name string
}
// Controller
type UserController struct {
service UserService
}
func (c *UserController) GetUser(w http.ResponseWriter, r *http.Request) {
// Lógica del controlador
}
2.2 Clean Architecture
Capas:
- Entities: Estructuras de datos básicas
- Use Cases: Reglas de negocio
- Interface Adapters: Convertidores de datos
- Frameworks & Drivers: Capa externa (DB, UI)
2.3 CQRS (Command Query Responsibility Segregation)
type CommandHandler interface {
Handle(command any) error
}
type QueryHandler interface {
Handle(query any) (any, error)
}
2.4 Event-Driven Architecture
type EventBus struct {
subscribers map[string][]chan any
}
func (eb *EventBus) Publish(eventName string, data any) {
// Notificar a todos los suscriptores
}
2.5 Microservicios
services/
├── user-service/
├── order-service/
└── payment-service/
3. Patrones de Diseño en Go
3.1 Patrones Creacionales
Singleton
type Database struct {
conn *sql.DB
}
var instance *Database
var once sync.Once
func GetInstance() *Database {
once.Do(func() {
instance = &Database{conn: initDB()}
})
return instance
}
Factory
type PaymentMethod interface {
Pay(amount float64) string
}
func GetPaymentMethod(method string) PaymentMethod {
switch method {
case "credit":
return &CreditCard{}
case "paypal":
return &PayPal{}
default:
return nil
}
}
3.2 Patrones Estructurales
Adapter
type LegacyPrinter interface {
Print(s string) string
}
type ModernPrinter interface {
PrintStored() string
}
type PrinterAdapter struct {
LegacyPrinter LegacyPrinter
Msg string
}
3.3 Patrones de Comportamiento
Strategy
type CompressionStrategy interface {
Compress(data []byte) []byte
}
type ZipStrategy struct{}
type RarStrategy struct{}
type Compressor struct {
strategy CompressionStrategy
}
4. Concurrencia en Go
4.1 Patrones de Concurrencia
Worker Pool
func worker(id int, jobs <-chan int, results chan<- int) {
for job := range jobs {
// Procesar trabajo
results <- job * 2
}
}
func main() {
jobs := make(chan int, 100)
results := make(chan int, 100)
// Iniciar workers
for w := 1; w <= 3; w++ {
go worker(w, jobs, results)
}
// Enviar trabajos
for j := 1; j <= 9; j++ {
jobs <- j
}
close(jobs)
// Recibir resultados
for a := 1; a <= 9; a++ {
<-results
}
}
Fan-Out/Fan-In
func fanOut(input <-chan int, outputs []chan int) {
for data := range input {
for _, out := range outputs {
out <- data
}
}
}
func fanIn(inputs ...<-chan int) <-chan int {
var wg sync.WaitGroup
out := make(chan int)
// ... configuración de merge ...
return out
}
4.2 Sync Package
var mu sync.Mutex
var rwMu sync.RWMutex
var once sync.Once
var pool = sync.Pool{
New: func() any {
return &Buffer{}
},
}
5. Otras Consideraciones
- Dependency Management: Usar Go Modules (
go.mod) - Configuración: Implementar patrones para manejo de configuración
- Logging: Usar interfaces para logging
- Error Handling: Patrones de manejo de errores centralizados
- Testing:
- Unit Tests
- Integration Tests
- Mocking (usar interfaces)
- CI/CD: Integración con GitHub Actions, GitLab CI, etc.
6. Ejemplo Completo (Clean Architecture + CQRS)
// Entidad
type User struct {
ID uuid.UUID
Name string
Email string
}
// Use Case
type UserService struct {
repo UserRepository
}
func (s *UserService) CreateUser(name, email string) (*User, error) {
user := &User{
ID: uuid.New(),
Name: name,
Email: email,
}
return user, s.repo.Save(user)
}
// Repositorio (Interfaz)
type UserRepository interface {
Save(user *User) error
FindByID(id uuid.UUID) (*User, error)
}
// Controlador HTTP
type UserHandler struct {
service *UserService
}
func (h *UserHandler) CreateUser(w http.ResponseWriter, r *http.Request) {
// Parsear request
// Llamar al servicio
// Devolver respuesta
}
7. Recursos Recomendados
- Libro: “Go Design Patterns”
- Patrones de Concurrencia
- Arquitectura Hexagonal en Go
- Ejemplo Clean Architecture
Este es un resumen completo de arquitecturas y patrones en Go. Cada sección podría profundizarse con implementaciones específicas y optimizaciones. La elección de arquitectura y patrones debe basarse en los requisitos específicos del proyecto.