Menu
Coddy logo textTech

Introduction aux Design Patterns

Fait partie de la section Programmation Orientée Objet du Journey GO de Coddy — leçon 85 sur 107.

Les patrons de conception (design patterns) sont des solutions réutilisables aux problèmes courants qui surviennent lors de la conception de logiciels. Ce ne sont pas des morceaux de code que vous copiez directement, mais plutôt des modèles qui guident la manière dont vous structurez vos types et leurs interactions pour résoudre des défis spécifiques.

Les patrons de conception sont généralement regroupés en trois catégories :

CatégorieObjectifExemples
CréationMécanismes de création d'objetsSingleton, Factory, Builder
StructureComposition de types en structures plus largesAdapter, Decorator, Composite
ComportementCommunication entre les objetsObserver, Strategy, Command

En Go, les patrons de conception sont différents de ceux des langages de POO traditionnels.

Sans classes ni héritage, Go implémente des modèles en utilisant des interfaces, l'imbrication de structures (struct embedding) et la composition. Par exemple, là où Java pourrait utiliser une classe abstraite, Go utilise une interface. Là où C++ pourrait utiliser l'héritage, Go utilise l'imbrication.

Apprendre les patrons de conception vous aide à reconnaître les problèmes courants et à communiquer des solutions efficacement avec d'autres développeurs. Quand quelqu'un mentionne « utilisez le patron Stratégie ici », toute l'équipe comprend l'approche sans explications interminables.

Au cours des prochaines leçons, vous implémenterez plusieurs patrons fondamentaux en Go, en commençant par les patrons de création tels que Singleton et Factory, puis en passant aux patrons de comportement tels que Observer et Strategy.

challenge icon

Défi

Facile

Construisons un système de notification simple qui démontre comment les patrons de conception aident à organiser le code ! Vous allez créer une structure qui pourrait facilement être étendue avec des patrons comme Observer ou Strategy dans de futures leçons—mais pour l'instant, concentrez-vous sur la mise en place d'interfaces et de types propres qui suivent les bons principes de la POO.

Vous organiserez votre code sur trois fichiers :

  • notifier.go : Définissez l'interface principale et les types pour votre système de notification.

    Créez une interface Notifier avec une seule méthode Send(message string) string qui retourne un message de confirmation.

    Implémentez deux types de notificateurs concrets :

    • EmailNotifier avec un champ Address—sa méthode Send retourne Email to [address]: [message]
    • SMSNotifier avec un champ PhoneNumber—sa méthode Send retourne SMS to [phone]: [message]
  • dispatcher.go : Créez un répartiteur qui fonctionne avec n'importe quel notificateur via l'interface.

    Construisez une structure NotificationDispatcher qui contient une tranche (slice) d'interfaces Notifier. Ajoutez ces méthodes :

    • AddNotifier(n Notifier) pour enregistrer un notificateur
    • Broadcast(message string) []string qui envoie le message via tous les notificateurs enregistrés et retourne une tranche de toutes les chaînes de confirmation

    Créez également un constructeur NewNotificationDispatcher() qui retourne un répartiteur initialisé.

  • main.go : Configurez les notificateurs et diffusez les messages.

    Lisez un nombre de notificateurs à créer. Pour chaque notificateur, lisez son type (email ou sms) et sa destination (adresse ou numéro de téléphone). Ajoutez chacun à un répartiteur.

    Ensuite, lisez un message à diffuser. Envoyez-le via tous les notificateurs et affichez chaque confirmation sur sa propre ligne.

Les entrées suivantes seront fournies :

  • Ligne 1 : Nombre de notificateurs
  • Pour chaque notificateur : type (email ou sms), puis destination
  • Dernière ligne : Message à diffuser

Par exemple, avec :

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

Votre sortie devrait être :

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

Et avec :

2
sms
555-9999
sms
555-0000
Meeting canceled

Votre sortie devrait être :

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

Cette structure démontre comment les interfaces permettent des conceptions flexibles et extensibles. Le répartiteur ne connaît pas les types de notificateurs spécifiques—il sait simplement qu'ils peuvent Send. C'est la base sur laquelle reposent des patrons comme Observer et Strategy !

Aide-mémoire

Les patrons de conception (design patterns) sont des solutions réutilisables à des problèmes courants de conception logicielle. Ce sont des modèles qui guident la manière de structurer les types et leurs interactions.

Les patrons de conception sont regroupés en trois catégories :

CatégorieObjectifExemples
CréationMécanismes de création d'objetsSingleton, Factory, Builder
StructurelComposition de types en structures plus largesAdapter, Decorator, Composite
ComportementalCommunication entre objetsObserver, Strategy, Command

En Go, les patrons de conception sont implémentés en utilisant des interfaces, l'imbrication de structures (struct embedding) et la composition au lieu des classes et de l'héritage. Là où les langages de POO traditionnels utilisent des classes abstraites, Go utilise des interfaces. Là où ils utilisent l'héritage, Go utilise l'imbrication.

Essayez vous-même

package main

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

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

	// Lire le nombre de notificateurs
	countStr, _ := reader.ReadString('\n')
	count, _ := strconv.Atoi(strings.TrimSpace(countStr))

	// Créer un nouveau dispatcher
	dispatcher := NewNotificationDispatcher()

	// Lire chaque notificateur et l'ajouter au dispatcher
	for i := 0; i < count; i++ {
		notifierType, _ := reader.ReadString('\n')
		notifierType = strings.TrimSpace(notifierType)

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

		// TODO: Créer le notificateur approprié en fonction du type
		// et l'ajouter au dispatcher
		// Hint: Vérifier si notifierType est "email" ou "sms"

	}

	// Lire le message à diffuser
	message, _ := reader.ReadString('\n')
	message = strings.TrimSpace(message)

	// TODO: Diffuser le message et afficher chaque confirmation

}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation Orientée Objet