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 projeto de software. Eles não são códigos que você copia diretamente, mas sim modelos que orientam como estruturar seus tipos e suas interações para resolver desafios específicos.

Os padrões de projeto normalmente são agrupados em três categorias:

CategoriaFinalidadeExemplos
CriacionaisMecanismos de criação de objetosSingleton, Factory, Builder
EstruturaisComposição de tipos em estruturas maioresAdapter, Decorator, Composite
ComportamentaisComunicação entre objetosObserver, Strategy, Command

Em Go, os padrões de projeto são diferentes dos padrões em linguagens tradicionais de POO.

Sem classes ou herança, Go implementa padrões usando interfaces, incorporação de structs e composição. Por exemplo, onde Java poderia usar uma classe abstrata, Go usa uma interface. Onde C++ poderia usar herança, 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 explicações longas.

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

challenge icon

Desafio

Fácil

Vamos criar um sistema simples de notificações que demonstra como os padrões de projeto 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 bem organizados 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 do seu sistema de notificações.

    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 notificadores:

    • 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 dispatcher que funcione com qualquer notificador por meio da interface.

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

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

    Crie também um construtor NewNotificationDispatcher() que retorne um dispatcher inicializado.

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

    Leia uma quantidade 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 dispatcher.

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

As entradas a seguir serão fornecidas:

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

Por exemplo, dadas as entradas:

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

Sua saída deverá 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 dadas as entradas:

2
sms
555-9999
sms
555-0000
Meeting canceled

Sua saída deverá ser:

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

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

Experimente você mesmo

package main

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

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

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

	// Criar um novo dispatcher
	dispatcher := NewNotificationDispatcher()

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

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

		// TODO: Criar o notificador apropriado com base no tipo
		// e adicioná-lo ao dispatcher
		// Dica: Verifique se notifierType é "email" ou "sms"

	}

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

	// TODO: Transmitir a mensagem e imprimir 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

Pratique por conta própria: Compilador de Go online