Menu
Coddy logo textTech

Introdução aos Padrões de Projeto

Parte da seção Programação Orientada a Objetos do Journey de GO da Coddy — lição 85 de 107.

Padrões de projeto são soluções reutilizáveis para problemas comuns que surgem no design de software. Eles não são códigos que você copia diretamente, mas sim modelos que orientam como você estrutura seus tipos e suas interações para resolver desafios específicos.

Padrões de projeto são tipicamente agrupados em três categorias:

CategoriaPropósitoExemplos
CriacionalMecanismos de criação de objetosSingleton, Factory, Builder
EstruturalComposição de tipos em estruturas maioresAdapter, Decorator, Composite
ComportamentalComunicação entre objetosObserver, Strategy, Command

Em Go, os padrões de projeto parecem diferentes do que em linguagens POO tradicionais.

Sem classes ou herança, o Go implementa padrões usando interfaces, incorporação de structs e composição. Por exemplo, onde o Java poderia usar uma classe abstrata, o Go usa uma interface. Onde o C++ poderia usar herança, o Go usa incorporação.

Aprender padrões ajuda você a reconhecer problemas comuns e a comunicar soluções de forma eficaz com outros desenvolvedores. Quando alguém menciona "use o padrão Strategy aqui", toda a equipe entende a abordagem sem a necessidade de explicações longas.

Nas próximas lições, você implementará vários padrões fundamentais em Go, começando com padrões de criação como Singleton e Factory, e depois passando para padrões comportamentais como Observer e Strategy.

challenge icon

Desafio

Fácil

Vamos construir um sistema de notificação simples que demonstra como os padrões de design ajudam a organizar o código! Você criará uma estrutura que poderá ser facilmente estendida com padrões como Observer ou Strategy em lições futuras — mas, por enquanto, concentre-se em configurar interfaces e tipos limpos que sigam bons princípios de OOP.

Você organizará seu código em três arquivos:

  • notifier.go: Defina a interface principal e os tipos para o seu sistema de notificação.

    Crie uma interface Notifier com um único método Send(message string) string que retorna uma mensagem de confirmação.

    Implemente dois tipos concretos de notificador:

    • EmailNotifier com um campo Address — seu método Send retorna Email to [address]: [message]
    • SMSNotifier com um campo PhoneNumber — seu método Send retorna SMS to [phone]: [message]
  • dispatcher.go: Crie um despachante que funcione com qualquer notificador por meio da interface.

    Construa uma struct NotificationDispatcher que contenha um slice de interfaces Notifier. Adicione estes métodos:

    • AddNotifier(n Notifier) para registrar um notificador
    • Broadcast(message string) []string que envia a mensagem através de todos os notificadores registrados e retorna um slice de todas as strings de confirmação

    Também crie um construtor NewNotificationDispatcher() que retorna um despachante inicializado.

  • main.go: Configure os notificadores e transmita as mensagens.

    Leia uma contagem de notificadores a serem criados. Para cada notificador, leia seu tipo (email ou sms) e seu destino (endereço ou número de telefone). Adicione cada um a um despachante.

    Em seguida, leia uma mensagem para transmitir. Envie-a através de todos os notificadores e imprima cada confirmação em sua própria linha.

As seguintes entradas serão fornecidas:

  • Linha 1: Número de notificadores
  • Para cada notificador: tipo (email ou sms), depois o destino
  • Linha final: Mensagem para transmitir

Por exemplo, dado:

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

Sua saída deve 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

E dado:

2
sms
555-9999
sms
555-0000
Meeting canceled

Sua saída deve ser:

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

Esta estrutura demonstra como as interfaces permitem designs flexíveis e extensíveis. O despachante não conhece os tipos específicos de notificador — ele apenas sabe que eles podem Send. Esta é a base sobre a qual padrões como Observer e Strategy são construídos!

Folha de consulta

Padrões de projeto são soluções reutilizáveis para problemas comuns no design de software. Eles são modelos que orientam como estruturar tipos e suas interações.

Padrões de projeto são agrupados em três categorias:

CategoriaObjetivoExemplos
CriacionalMecanismos de criação de objetosSingleton, Factory, Builder
EstruturalComposição de tipos em estruturas maioresAdapter, Decorator, Composite
ComportamentalComunicação entre objetosObserver, Strategy, Command

Em Go, os padrões de projeto são implementados usando interfaces, incorporação de structs e composição, em vez de classes e herança. Onde as linguagens POO tradicionais usam classes abstratas, Go usa interfaces. Onde elas usam herança, Go usa incorporação.

Experimente você mesmo

package main

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

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

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

	// Cria um novo despachante
	dispatcher := NewNotificationDispatcher()

	// Lê cada notificador e adiciona ao despachante
	for i := 0; i < count; i++ {
		notifierType, _ := reader.ReadString('\n')
		notifierType = strings.TrimSpace(notifierType)

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

		// TODO: Cria o notificador apropriado com base no tipo
		// e adiciona-o ao despachante
		// Dica: Verifique se notifierType é "email" ou "sms"

	}

	// Lê a mensagem para transmitir
	message, _ := reader.ReadString('\n')
	message = strings.TrimSpace(message)

	// TODO: Transmite a mensagem e imprime cada confirmação

}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos