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.

Los patrones de diseño son soluciones reutilizables para problemas comunes que surgen en el diseño de software. No son código que copies directamente, sino plantillas que guían la forma en que estructuras tus tipos y sus interacciones para resolver desafíos específicos.

Los patrones de diseño normalmente 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 son diferentes a los de los lenguajes OOP tradicionales.

Sin clases ni herencia, Go implementa patrones mediante interfaces, la inclusión de estructuras y la composición. Por ejemplo, donde Java podría usar una clase abstracta, Go usa una interfaz. Donde C++ podría usar herencia, Go usa la inclusión.

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

En las próximas lecciones, implementarás varios patrones fundamentales en Go, empezando por patrones creacionales como Singleton y Factory, y después pasando a patrones de comportamiento como Observer y Strategy.

challenge icon

Desafío

Fácil

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

Organizarás tu código en tres archivos:

  • notifier.go: Define la interfaz principal y los tipos de tu sistema de notificaciones.

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

    Implementa dos tipos concretos de notificador:

    • 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 mediante 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

    Crea también un constructor NewNotificationDispatcher() que devuelva un despachador inicializado.

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

    Lee la cantidad de notificadores que se deben 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.

    Después, lee un mensaje para difundir. 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), después el destino
  • Línea final: Mensaje que se difundirá

Por ejemplo, dada la siguiente entrada:

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 dada la siguiente entrada:

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 ampliables. El despachador no conoce los tipos específicos de notificadores. Solo sabe que pueden ejecutar Send. ¡Esta es la base sobre la que se construyen patrones como Observer y Strategy!

Pruébalo tú mismo

package main

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

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

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

	// Crea un nuevo dispatcher
	dispatcher := NewNotificationDispatcher()

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

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

		// TODO: Crea el notificador apropiado según el tipo
		// y añádelo al dispatcher
		// Hint: Comprueba si notifierType es "email" o "sms"

	}

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

	// TODO: Transmite el mensaje e imprime 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

Practica por tu cuenta: Compilador de Go online