Patrones de constructores
Creación de constructores idiomáticos en Go
Patrones de constructores es una lección gratuita de Go Academy en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Go Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Go Academy incluye 4 lecciones en total.
¿Por qué usar constructores?
Go no tiene una palabra clave new para los tipos ni constructores de clases. La convención consiste en usar una función llamada New... que valide las entradas y devuelva un valor o puntero inicializado.
Función New sencilla
Devuelva un puntero para garantizar que quien realiza la llamada trabaje con una instancia compartida:
package main
import "fmt"
type Server struct {
Host string
Port int
}
func NewServer(host string, port int) *Server {
return &Server{Host: host, Port: port}
}
func main() {
s := NewServer("localhost", 8080)
fmt.Println(s.Host, s.Port)
}Validación en constructores
Los constructores son un buen lugar para validar las entradas y devolver un error:
package main
import ("errors"; "fmt")
type Config struct{ Workers int }
func NewConfig(workers int) (*Config, error) {
if workers < 1 {
return nil, errors.New("workers must be >= 1")
}
return &Config{Workers: workers}, nil
}
func main() {
c, err := NewConfig(4)
fmt.Println(c, err)
}Patrón de opciones funcionales
El patrón de opciones funcionales permite configurar opciones sin romper la API:
package main
import "fmt"
type Server struct{ host string; port int; timeout int }
type Option func(*Server)
func WithPort(p int) Option { return func(s *Server) { s.port = p } }
func WithTimeout(t int) Option { return func(s *Server) { s.timeout = t } }
func NewServer(host string, opts ...Option) *Server {
s := &Server{host: host, port: 8080, timeout: 30}
for _, o := range opts { o(s) }
return s
}
func main() {
s := NewServer("localhost", WithPort(9090), WithTimeout(60))
fmt.Println(s.port, s.timeout)
}Patrón builder
Para objetos complejos, el patrón builder encadena métodos configuradores y devuelve el resultado:
package main
import "fmt"
type QueryBuilder struct{ table, where string; limit int }
func (q *QueryBuilder) Table(t string) *QueryBuilder { q.table = t; return q }
func (q *QueryBuilder) Where(w string) *QueryBuilder { q.where = w; return q }
func (q *QueryBuilder) Limit(n int) *QueryBuilder { q.limit = n; return q }
func (q *QueryBuilder) Build() string {
return fmt.Sprintf("SELECT * FROM %s WHERE %s LIMIT %d", q.table, q.where, q.limit)
}
func main() {
sql := (&QueryBuilder{}).Table("users").Where("age>18").Limit(10).Build()
fmt.Println(sql)
}Devolver un valor o un puntero
Devuelva un valor cuando el struct sea pequeño e inmutable; devuelva un puntero cuando sea grande o mutable, o cuando implemente interfaces:
- Structs de configuración pequeños → valor
- Objetos con estado (servidor, cliente, pool) → puntero
- Si implementa una interfaz con receptores por puntero → puntero
Patrón de valores predeterminados
Use una función de valores predeterminados o un literal de struct para establecer valores razonables antes de aplicar las opciones:
package main
import "fmt"
type Cache struct{ maxSize int; ttlSecs int }
func defaultCache() Cache { return Cache{maxSize: 100, ttlSecs: 300} }
func NewCache(opts ...func(*Cache)) *Cache {
c := defaultCache()
for _, o := range opts { o(&c) }
return &c
}
func main() {
c := NewCache(func(c *Cache) { c.maxSize = 500 })
fmt.Println(c.maxSize, c.ttlSecs) // 500 300
}Patrón singleton
Use sync.Once para inicializar un recurso compartido exactamente una vez:
package main
import ("fmt"; "sync")
type DB struct{ DSN string }
var (
instance *DB
once sync.Once
)
func GetDB(dsn string) *DB {
once.Do(func() { instance = &DB{DSN: dsn} })
return instance
}
func main() {
db1 := GetDB("postgres://...")
db2 := GetDB("ignored")
fmt.Println(db1 == db2) // true
}Pruebas de constructores
Los constructores que devuelven errores son fáciles de probar:
package main
import ("errors"; "fmt")
type Pool struct{ size int }
func NewPool(size int) (*Pool, error) {
if size <= 0 { return nil, errors.New("size must be positive") }
return &Pool{size: size}, nil
}
func main() {
_, err := NewPool(-1)
fmt.Println(err) // size must be positive
p, _ := NewPool(5)
fmt.Println(p.size) // 5
}Evite init()
Las funciones init() se ejecutan automáticamente y son difíciles de probar. Prefiera constructores explícitos que devuelvan errores en lugar de la inicialización implícita en init().
Comprobación rápida
¿Qué consigue el patrón de opciones funcionales?
Recapitulación: patrones de constructores
Conclusiones principales:
- Use funciones
New...como constructores - Devuelva errores cuando falle la validación
- Use opciones funcionales para una configuración opcional flexible
- Use el patrón builder para objetos complejos de consulta o configuración
- Prefiera constructores explícitos en lugar de
init()
Ejercicio práctico
Implemente un constructor NewHTTPClient mediante opciones funcionales. Admite las opciones WithTimeout, WithBaseURL y WithMaxRetries.
Preguntas frecuentes
¿La lección «Patrones de constructores» es gratis?
Sí — el texto completo de «Patrones de constructores» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Go Academy, actualiza a CoddyKit PRO. El curso de Go Academy incluye 4 lecciones en total.
¿Qué aprenderé en «Patrones de constructores»?
Creación de constructores idiomáticos en Go Practicas Go Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Go Academy?
No se requiere experiencia previa. Go Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.
¿Cuánto tiempo toma la lección «Patrones de constructores»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Go Academy?
Sí. Cada lección de Go Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Definición y uso de structs
- Métodos en structs
- Patrones de constructores
- Structs anónimos y composición