Menu
Coddy logo textTech

Factory-Muster

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

Das Factory pattern delegiert die Objekterstellung an eine separate Funktion oder Methode und ermöglicht es dir, Instanzen zu erstellen, ohne die Erstellungslogik offenzulegen. Im Gegensatz zum Singleton, das die Anzahl der Instanzen steuert, konzentriert sich die Factory auf die flexible Objekterstellung anhand von Eingabeparametern.

In Go ist eine Factory typischerweise eine Funktion, die einen Schnittstellentyp zurückgibt und es dir ermöglicht, verschiedene konkrete Typen über eine einheitliche API zu erstellen:

type Notifier interface {
    Send(message string) string
}

type EmailNotifier struct{}
type SMSNotifier struct{}

func (e EmailNotifier) Send(message string) string {
    return "Email: " + message
}

func (s SMSNotifier) Send(message string) string {
    return "SMS: " + message
}

func NewNotifier(notifierType string) Notifier {
    switch notifierType {
    case "email":
        return EmailNotifier{}
    case "sms":
        return SMSNotifier{}
    default:
        return EmailNotifier{}
    }
}

Die Fabrikfunktion NewNotifier kapselt die Entscheidung darüber, welchen konkreten Typ erstellt werden soll. Der Client-Code arbeitet nur mit dem Notifier-Interface und bleibt von der spezifischen Implementierung unberührt:

notifier := NewNotifier("sms")
result := notifier.Send("Hello!")  // "SMS: Hello!"

Dieses Muster ist besonders nützlich, wenn du Objekte basierend auf Laufzeitbedingungen erstellen musst, komplexe Initialisierungslogik zentralisieren möchtest oder problemlos neue Typen hinzufügen musst, ohne den Client-Code zu ändern. Füge einfach eine neue Struktur hinzu, die das Interface implementiert, und aktualisiere die Factory-Funktion.

challenge icon

Aufgabe

Einfach

Lass uns ein Dokumentkonvertersystem mithilfe des Fabrikmusters erstellen! Du wirst eine Fabrik erstellen, die abhängig vom Zielformat verschiedene Dokumentkonverter erzeugt, sodass der Clientcode über eine einheitliche Schnittstelle mit jedem Konverter arbeiten kann.

Du wirst deinen Code auf zwei Dateien aufteilen:

  • converter.go: Definiere deine Konverterschnittstelle und konkrete Implementierungen.

    Erstelle eine Converter-Schnittstelle mit einer Methode Convert(content string) string, die den Dokumentinhalt übernimmt und die konvertierte Ausgabe zurückgibt.

    Implementiere drei Konvertertypen:

    • PDFConverter: Die Methode Convert gibt PDF: [content] zurück
    • HTMLConverter: Die Methode Convert gibt HTML: <p>[content]</p> zurück
    • MarkdownConverter: Die Methode Convert gibt MD: # [content] zurück

    Erstelle eine Fabrikfunktion NewConverter(format string) Converter, die abhängig vom Format-String (pdf, html oder markdown) den passenden Konverter zurückgibt. Gib für jedes nicht erkannte Format standardmäßig einen PDFConverter zurück.

  • main.go: Verwende deine Fabrik, um Konverter zu erstellen und Dokumente zu verarbeiten.

    Lies einen Formattyp und den Dokumentinhalt ein. Verwende die Fabrik, um den passenden Konverter zu erstellen, konvertiere anschließend den Inhalt und gib das Ergebnis aus.

Die folgenden Eingaben werden bereitgestellt:

  • Zeile 1: Formattyp (pdf, html, markdown oder etwas anderes)
  • Zeile 2: Zu konvertierender Dokumentinhalt

Zum Beispiel bei:

html
Welcome to Go Programming

Deine Ausgabe sollte sein:

HTML: <p>Welcome to Go Programming</p>

Und bei:

markdown
Chapter One

Deine Ausgabe sollte sein:

MD: # Chapter One

Und bei:

pdf
Annual Report 2024

Deine Ausgabe sollte sein:

PDF: Annual Report 2024

Und bei:

docx
Meeting Notes

Deine Ausgabe sollte sein:

PDF: Meeting Notes

Beachte, dass der Hauptcode die spezifischen Konvertertypen nicht kennen muss. Er fordert einfach einen Konverter von der Fabrik an und verwendet die Schnittstelle. Dadurch lassen sich später problemlos neue Formate hinzufügen, ohne den Clientcode zu ändern!

Probier es selbst

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	
	// Formattyp lesen
	scanner.Scan()
	format := scanner.Text()
	
	// Dokumentinhalt lesen
	scanner.Scan()
	content := scanner.Text()
	
	// TODO: Verwende die Factory, um den entsprechenden Converter zu erstellen
	// TODO: Konvertiere den Inhalt und gib das Ergebnis aus
	
	fmt.Println(result)
}
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