Menu
Coddy logo textTech

Introducción a los patrones de diseño

Parte de la sección Programación Orientada a Objetos del Journey de GO de Coddy — lección 85 de 107.

Patrones de diseño son soluciones reutilizables a problemas comunes que surgen en el diseño de software. No son código que se copia directamente, sino más bien plantillas que guían cómo estructurar tus tipos y sus interacciones para resolver desafíos específicos.

Los patrones de diseño se agrupan típicamente en tres categorías:

CategoríaPropósitoEjemplos
CreacionalesMecanismos de creación de objetosSingleton, Factory, Builder
EstructuralesComposición de tipos en estructuras más grandesAdapter, Decorator, Composite
De comportamientoComunicación entre objetosObserver, Strategy, Command

En Go, los patrones de diseño se ven diferentes que en los lenguajes de POO tradicionales.

Sin classes ni herencia, Go implementa patrones utilizando interfaces, struct embedding y composición. Por ejemplo, donde Java podría usar una abstract class, Go usa una interface. Donde C++ podría usar herencia, Go usa embedding.

Aprender patrones te ayuda a reconocer problemas comunes y a comunicar soluciones de manera efectiva con otros desarrolladores. Cuando alguien menciona "usa el patrón Strategy aquí", todo el equipo entiende el enfoque sin necesidad de explicaciones extensas.

En las próximas lecciones, implementarás varios patrones fundamentales en Go, comenzando con patrones de creación como Singleton y Factory, para luego pasar a patrones de comportamiento como Observer y Strategy.

challenge icon

Desafío

Fácil

¡Vamos a construir un sistema de notificación sencillo que demuestre cómo los patrones de diseño ayudan a organizar el código! Crearás una estructura que podría extenderse fácilmente con patrones como Observer o Strategy en futuras lecciones, pero por ahora, concéntrate en configurar interfaces y tipos limpios que sigan los buenos principios de la POO.

Organizarás tu código en tres archivos:

  • notifier.go: Define la interfaz principal y los tipos para tu sistema de notificación.

    Crea una interfaz Notifier con un único método Send(message string) string que devuelva un mensaje de confirmación.

    Implementa dos tipos de notificadores concretos:

    • EmailNotifier con un campo Address: su método Send devuelve Email to [address]: [message]
    • SMSNotifier con un campo PhoneNumber: su método Send devuelve SMS to [phone]: [message]
  • dispatcher.go: Crea un despachador que funcione con cualquier notificador a través de la interfaz.

    Construye una estructura NotificationDispatcher que contenga un slice de interfaces Notifier. Añade estos métodos:

    • AddNotifier(n Notifier) para registrar un notificador
    • Broadcast(message string) []string que envíe el mensaje a través de todos los notificadores registrados y devuelva un slice con todas las cadenas de confirmación

    También crea un constructor NewNotificationDispatcher() que devuelva un despachador inicializado.

  • main.go: Configura los notificadores y transmite los mensajes.

    Lee una cantidad de notificadores a crear. Para cada notificador, lee su tipo (email o sms) y su destino (dirección o número de teléfono). Añade cada uno a un despachador.

    Luego lee un mensaje para transmitir. Envíalo a través de todos los notificadores e imprime cada confirmación en su propia línea.

Se proporcionarán las siguientes entradas:

  • Línea 1: Número de notificadores
  • Para cada notificador: tipo (email o sms), luego el destino
  • Línea final: Mensaje a transmitir

Por ejemplo, dado:

3
email
alice@example.com
sms
555-1234
email
bob@example.com
Server maintenance at midnight

Tu salida debería ser:

Email to alice@example.com: Server maintenance at midnight
SMS to 555-1234: Server maintenance at midnight
Email to bob@example.com: Server maintenance at midnight

Y dado:

2
sms
555-9999
sms
555-0000
Meeting canceled

Tu salida debería ser:

SMS to 555-9999: Meeting canceled
SMS to 555-0000: Meeting canceled

Esta estructura demuestra cómo las interfaces permiten diseños flexibles y extensibles. El despachador no conoce los tipos específicos de notificadores; solo sabe que pueden ejecutar Send. ¡Esta es la base sobre la cual se construyen patrones como Observer y Strategy!

Hoja de referencia

Los patrones de diseño son soluciones reutilizables a problemas comunes en el diseño de software. Son plantillas que guían cómo estructurar los tipos y sus interacciones.

Los patrones de diseño se agrupan en tres categorías:

CategoríaPropósitoEjemplos
CreacionalesMecanismos de creación de objetosSingleton, Factory, Builder
EstructuralesComposición de tipos en estructuras más grandesAdapter, Decorator, Composite
De comportamientoComunicación entre objetosObserver, Strategy, Command

En Go, los patrones de diseño se implementan utilizando interfaces, incrustación de estructuras (struct embedding) y composición en lugar de clases y herencia. Donde los lenguajes de POO tradicionales utilizan clases abstractas, Go utiliza interfaces. Donde utilizan herencia, Go utiliza incrustación.

Pruébalo tú mismo

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	// Leer el número de notificadores
	countStr, _ := reader.ReadString('\n')
	count, _ := strconv.Atoi(strings.TrimSpace(countStr))

	// Crear un nuevo despachador
	dispatcher := NewNotificationDispatcher()

	// Leer cada notificador y añadirlo al despachador
	for i := 0; i < count; i++ {
		notifierType, _ := reader.ReadString('\n')
		notifierType = strings.TrimSpace(notifierType)

		destination, _ := reader.ReadString('\n')
		destination = strings.TrimSpace(destination)

		// TODO: Crear el notificador apropiado basado en el tipo
		// y añadirlo al despachador
		// Pista: Comprobar si notifierType es "email" o "sms"

	}

	// Leer el mensaje a difundir
	message, _ := reader.ReadString('\n')
	message = strings.TrimSpace(message)

	// TODO: Difundir el mensaje e imprimir cada confirmación

}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos