Menu
Coddy logo textTech

Builder-Pattern in Go

Teil des Abschnitts Objektorientierte Programmierung der GO-Journey von Coddy. Lektion 80 von 107.

Das Builder-Muster trennt die Erstellung eines komplexen Objekts von seiner Darstellung. Im Gegensatz zum Muster der funktionalen Optionen verwendet der Builder eine spezielle Builder-Struktur mit Methoden, die das Objekt Schritt für Schritt konfigurieren.

So implementierst du einen Builder für eine HTTP-Anfrage:

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
}

Jede Methode gibt den Builder-Zeiger zurück und ermöglicht dadurch das Verketten von Methoden. Die Methode Build() schließt die Erstellung ab und gibt das erstellte Objekt zurück:

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

Das Builder-Muster eignet sich hervorragend, wenn Objekte mehrere Konfigurationsschritte erfordern oder wenn du eine bestimmte Konstruktionsreihenfolge erzwingen möchtest. Es ist besonders nützlich zum Erstellen unveränderlicher Objekte oder wenn der Konstruktionsprozess selbst eine Validierung benötigt.

challenge icon

Aufgabe

Einfach

Erstellen wir einen E-Mail-Nachrichten-Composer mit dem Builder Pattern! E-Mail-Nachrichten haben viele optionale Bestandteile – Absender, Empfänger, CC, Betreff, Text und Anhänge – und eignen sich daher perfekt für eine schrittweise Erstellung mit Methodenverkettung.

Du organisierst deinen Code über zwei Dateien:

  • email.go: Definiere deine E-Mail-Struktur und ihren Builder.

    Erstelle eine Email-Struktur mit diesen Feldern:

    • from (String)
    • to (String-Slice)
    • cc (String-Slice)
    • subject (String)
    • body (String)

    Erstelle eine EmailBuilder-Struktur, die einen Zeiger auf eine gerade erstellte Email enthält. Implementiere NewEmailBuilder(), die einen neuen Builder mit einer initialisierten Email zurückgibt (leere Slices für to und cc).

    Füge diese Builder-Methoden hinzu, die jeweils *EmailBuilder für die Verkettung zurückgeben:

    • From(address string) – legt den Absender fest
    • To(address string) – fügt der to-Slice einen Empfänger hinzu
    • CC(address string) – fügt der cc-Slice einen Empfänger hinzu
    • Subject(subject string) – legt die Betreffzeile fest
    • Body(body string) – legt den E-Mail-Text fest

    Füge eine Build()-Methode hinzu, die die erstellte *Email zurückgibt.

    Füge schließlich eine Summary()-Methode zu Email hinzu, die einen String in diesem Format zurückgibt:

    From: [from]
    To: [comma-separated to addresses]
    CC: [comma-separated cc addresses or "none"]
    Subject: [subject]
    Body: [body]
  • main.go: Erstelle E-Mail-Nachrichten mit dem Builder und zeige sie an.

    Lies die Absenderadresse ein, dann die Anzahl der Empfänger und jede Empfängeradresse. Lies anschließend die Anzahl der CC-Empfänger und jede CC-Adresse ein. Lies zum Schluss den Betreff und den Text ein.

    Verwende den EmailBuilder mit Methodenverkettung, um die E-Mail zu erstellen, und gib anschließend ihre Zusammenfassung aus.

Die folgenden Eingaben werden bereitgestellt:

  • Zeile 1: Absenderadresse
  • Zeile 2: Anzahl der Empfänger
  • Folgende Zeilen: Jede Empfängeradresse
  • Nächste Zeile: Anzahl der CC-Empfänger
  • Folgende Zeilen: Jede CC-Adresse
  • Nächste Zeile: Betreff
  • Letzte Zeile: Text

Zum Beispiel bei folgender Eingabe:

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

Deine Ausgabe sollte folgendermaßen aussehen:

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.

Und bei folgender Eingabe:

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

Deine Ausgabe sollte folgendermaßen aussehen:

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

Beachte, wie der Builder dir ermöglicht, durch wiederholte Aufrufe von To() mehrere Empfänger einzeln hinzuzufügen, und wie das Muster den Erstellungsprozess auch bei vielen optionalen Feldern übersichtlich und gut lesbar hält.

Probier es selbst

package main

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

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

	// Absenderadresse lesen
	from, _ := reader.ReadString('\n')
	from = strings.TrimSpace(from)

	// Anzahl der Empfänger lesen
	toCountStr, _ := reader.ReadString('\n')
	toCount, _ := strconv.Atoi(strings.TrimSpace(toCountStr))

	// Jede Empfängeradresse lesen
	toAddresses := make([]string, toCount)
	for i := 0; i < toCount; i++ {
		addr, _ := reader.ReadString('\n')
		toAddresses[i] = strings.TrimSpace(addr)
	}

	// Anzahl der CC-Empfänger lesen
	ccCountStr, _ := reader.ReadString('\n')
	ccCount, _ := strconv.Atoi(strings.TrimSpace(ccCountStr))

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

	// Betreff lesen
	subject, _ := reader.ReadString('\n')
	subject = strings.TrimSpace(subject)

	// Nachrichtentext lesen
	body, _ := reader.ReadString('\n')
	body = strings.TrimSpace(body)

	// TODO: Verwende den EmailBuilder mit Method Chaining, um die E-Mail zu erstellen
	// Beginne mit NewEmailBuilder(), dann verketten From(), To(), CC(), Subject(), Body()
	// Rufe abschließend Build() auf, um die Email zu erhalten

	// TODO: Gib die E-Mail-Zusammenfassung mit der Summary()-Methode aus
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-Go-Compiler