Patrones de diseño en Go con ejemplos: de la A a la Z

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Patrones de diseño en Go con ejemplos: de la A a la Z



Los patrones de diseño (Design Patterns) son soluciones arquitectónicas probadas a lo largo del tiempo que ayudan a los desarrolladores de Go a crear código flexible, escalable y mantenible. A diferencia de los lenguajes clásicos de POO, Go ofrece su propio enfoque único para implementar patrones a través de interfaces, composición y gorutinas. En este artículo analizaremos los principales patrones de diseño en Go con ejemplos de código concretos.



1. Patrones creacionales (Creational Patterns)



Los patrones creacionales se encargan de la creación de objetos, haciendo que el sistema sea independiente de la forma en que se crean.



1.1. Singleton (Singleton)



Singleton garantiza que una clase tenga solo una instancia. En Go, esto se implementa a menudo mediante sync.Once para la seguridad en concurrencia.



package main

import ( "fmt" "sync")

type Database struct { connection string}

var ( instance *Database once sync.Once)

func GetDatabaseInstance() *Database { once.Do(func() { instance = &Database{connection: "postgres://localhost:5432/mydb"} fmt.Println("Creada única conexión a la BD") }) return instance}

func main() { db1 := GetDatabaseInstance() db2 := GetDatabaseInstance() fmt.Println(db1 == db2) // true}


1.2. Factory Method (Método Fábrica)



La fábrica delega la creación de objetos a las subclases. En Go, esto se hace mediante interfaces.



package main

import "fmt"

// Interfaz del productotype Transport interface { Deliver() string}

// Productos concretostype Truck struct{}func (t Truck) Deliver() string { return "Entrega por tierra" }

type Ship struct{}func (s Ship) Deliver() string { return "Entrega por mar" }

// Fábricatype LogisticsFactory interface { CreateTransport() Transport}

type RoadLogistics struct{}func (r RoadLogistics) CreateTransport() Transport { return Truck{} }

type SeaLogistics struct{}func (s SeaLogistics) CreateTransport() Transport { return Ship{} }

func main() { var factory LogisticsFactory = RoadLogistics{} transport := factory.CreateTransport() fmt.Println(transport.Deliver()) // Entrega por tierra}


2. Patrones estructurales (Structural Patterns)



Los patrones estructurales ayudan a organizar clases y objetos en estructuras más grandes.



2.1. Adapter (Adaptador)



El adaptador permite que objetos con interfaces incompatibles trabajen juntos. En Go, esto se resuelve mediante un envoltorio.



package main

import "fmt"

// Interfaz antiguatype OldPrinter interface { PrintOld(data string)}

type LegacyPrinter struct{}func (l LegacyPrinter) PrintOld(data string) { fmt.Println("Legacy:", data)}

// Nueva interfaztype NewPrinter interface { PrintNew(data string)}

// Adaptadortype PrinterAdapter struct { OldPrinter OldPrinter}

func (a PrinterAdapter) PrintNew(data string) { a.OldPrinter.PrintOld(data)}

func main() { legacy := LegacyPrinter{} adapter := PrinterAdapter{OldPrinter: legacy} adapter.PrintNew("¡Hola, Go!") // Legacy: ¡Hola, Go!}


2.2. Composite (Compuesto)



El compuesto permite tratar grupos de objetos como un solo objeto. Ideal para estructuras de árbol.



package main

import "fmt"

// Interfaz del componentetype Graphic interface { Draw() string}

// Elemento hojatype Circle struct{}func (c Circle) Draw() string { return "Dibujamos un círculo" }

// Contenedortype CompoundGraphic struct { children []Graphic}

func (cg *CompoundGraphic) Add(g Graphic) { cg.children = append(cg.children, g)}

func (cg *CompoundGraphic) Draw() string { result := "Figura compuesta:" for _, child := range cg.children { result += " - " + c

Blogs

Book Recommendations