Menu
Coddy logo textTech

Pattern Builder en Go

Fait partie de la section Programmation Orientée Objet du Journey GO de Coddy. Leçon 80 sur 107.

Le patron Builder sépare la construction d’un objet complexe de sa représentation. Contrairement au patron des options fonctionnelles, le Builder utilise une structure de construction dédiée avec des méthodes qui configurent l’objet étape par étape.

Voici comment implémenter un builder pour une requête HTTP :

type Request struct {
    method  string
    url     string
    headers map[string]string
    body    string
}

type RequestBuilder struct {
    request *Request
}

func NewRequestBuilder() *RequestBuilder {
    return &RequestBuilder{
        request: &Request{
            headers: make(map[string]string),
        },
    }
}

func (b *RequestBuilder) Method(m string) *RequestBuilder {
    b.request.method = m
    return b
}

func (b *RequestBuilder) URL(u string) *RequestBuilder {
    b.request.url = u
    return b
}

func (b *RequestBuilder) Header(key, value string) *RequestBuilder {
    b.request.headers[key] = value
    return b
}

func (b *RequestBuilder) Build() *Request {
    return b.request
}

Chaque méthode renvoie le pointeur vers le générateur, ce qui permet l’enchaînement des méthodes. La méthode Build() finalise et renvoie l’objet construit :

req := NewRequestBuilder().
    Method("POST").
    URL("https://api.example.com").
    Header("Content-Type", "application/json").
    Build()

Le modèle Builder est particulièrement adapté lorsque les objets nécessitent plusieurs étapes de configuration ou lorsque vous souhaitez imposer une séquence de construction spécifique. Il est particulièrement utile pour créer des objets immuables ou lorsque le processus de construction lui-même doit faire l’objet d’une validation.

challenge icon

Défi

Facile

Construisons un composeur de messages électroniques à l'aide du patron Builder ! Les messages électroniques comportent de nombreux composants facultatifs : destinataires, CC, objet, corps et pièces jointes, ce qui en fait des candidats parfaits pour une construction étape par étape avec un chaînage de méthodes.

Vous organiserez votre code sur deux fichiers :

  • email.go : définissez la structure de votre e-mail et son builder.

    Créez une structure Email avec les champs suivants :

    • from (chaîne de caractères)
    • to (tranche de chaînes de caractères)
    • cc (tranche de chaînes de caractères)
    • subject (chaîne de caractères)
    • body (chaîne de caractères)

    Créez une structure EmailBuilder qui contient un pointeur vers un Email en cours de construction. Implémentez NewEmailBuilder(), qui renvoie un nouveau builder avec un Email initialisé (des tranches vides pour to et cc).

    Ajoutez les méthodes de builder suivantes, chacune renvoyant *EmailBuilder pour permettre le chaînage :

    • From(address string) - définit l'expéditeur
    • To(address string) - ajoute un destinataire à la tranche to
    • CC(address string) - ajoute un destinataire à la tranche cc
    • Subject(subject string) - définit l'objet
    • Body(body string) - définit le corps de l'e-mail

    Ajoutez une méthode Build() qui renvoie le *Email construit.

    Enfin, ajoutez une méthode Summary() sur Email qui renvoie une chaîne dans ce format :

    From: [from]
    To: [comma-separated to addresses]
    CC: [comma-separated cc addresses or "none"]
    Subject: [subject]
    Body: [body]
  • main.go : construisez et affichez des messages électroniques à l'aide du builder.

    Lisez l'adresse de l'expéditeur, puis le nombre de destinataires et l'adresse de chaque destinataire. Ensuite, lisez le nombre de destinataires en CC et l'adresse de chacun d'eux. Enfin, lisez l'objet et le corps.

    Utilisez EmailBuilder avec le chaînage de méthodes pour construire l'e-mail, puis affichez son résumé.

Les entrées suivantes seront fournies :

  • Ligne 1 : adresse de l'expéditeur
  • Ligne 2 : nombre de destinataires
  • Lignes suivantes : adresse de chaque destinataire
  • Ligne suivante : nombre de destinataires en CC
  • Lignes suivantes : adresse de chaque destinataire en CC
  • Ligne suivante : objet
  • Dernière ligne : corps

Par exemple, avec :

alice@company.com
2
bob@company.com
carol@company.com
1
manager@company.com
Weekly Report
Please find the weekly report attached.

Votre sortie doit être :

From: alice@company.com
To: bob@company.com, carol@company.com
CC: manager@company.com
Subject: Weekly Report
Body: Please find the weekly report attached.

Et avec :

support@service.com
1
customer@email.com
0
Your Ticket Update
Your support ticket has been resolved.

Votre sortie doit être :

From: support@service.com
To: customer@email.com
CC: none
Subject: Your Ticket Update
Body: Your support ticket has been resolved.

Remarquez comment le builder vous permet d'ajouter plusieurs destinataires un par un grâce à des appels répétés à To(), et comment le patron garde le processus de construction propre et lisible, même avec de nombreux champs facultatifs.

Essayez vous-même

package main

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

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

	// Lire l'adresse de l'expéditeur
	from, _ := reader.ReadString('\n')
	from = strings.TrimSpace(from)

	// Lire le nombre de destinataires
	toCountStr, _ := reader.ReadString('\n')
	toCount, _ := strconv.Atoi(strings.TrimSpace(toCountStr))

	// Lire chaque adresse de destinataire
	toAddresses := make([]string, toCount)
	for i := 0; i < toCount; i++ {
		addr, _ := reader.ReadString('\n')
		toAddresses[i] = strings.TrimSpace(addr)
	}

	// Lire le nombre de destinataires en CC
	ccCountStr, _ := reader.ReadString('\n')
	ccCount, _ := strconv.Atoi(strings.TrimSpace(ccCountStr))

	// Lire chaque adresse CC
	ccAddresses := make([]string, ccCount)
	for i := 0; i < ccCount; i++ {
		addr, _ := reader.ReadString('\n')
		ccAddresses[i] = strings.TrimSpace(addr)
	}

	// Lire le sujet
	subject, _ := reader.ReadString('\n')
	subject = strings.TrimSpace(subject)

	// Lire le corps
	body, _ := reader.ReadString('\n')
	body = strings.TrimSpace(body)

	// TODO: Utiliser l'EmailBuilder avec le chaînage de méthodes pour construire l'email
	// Commencez avec NewEmailBuilder(), puis enchaînez From(), To(), CC(), Subject(), Body()
	// Enfin, appelez Build() pour obtenir l'Email

	// TODO: Afficher le résumé de l'email en utilisant la méthode Summary()
}
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

Entraînez-vous par vous-même : Compilateur Go en ligne