Wzorzec Factory
Część sekcji Programowanie obiektowe ścieżki GO w Coddy. Lekcja 87 z 107.
Wzorzec fabryki deleguje tworzenie obiektów do osobnej funkcji lub metody, umożliwiając tworzenie instancji bez ujawniania logiki ich tworzenia. W przeciwieństwie do Singletona, który kontroluje liczbę instancji, fabryka koncentruje się na elastycznym tworzeniu obiektów w zależności od parametrów wejściowych.
W Go fabryka to zazwyczaj funkcja zwracająca typ interfejsowy, dzięki czemu można tworzyć różne typy konkretne za pośrednictwem ujednoliconego API:
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{}
}
}Funkcja fabrykująca NewNotifier kapsułkuje decyzję o tym, jaki konkretny typ utworzyć. Kod klienta korzysta wyłącznie z interfejsu Notifier, nie wiedząc, jaka jest konkretna implementacja:
notifier := NewNotifier("sms")
result := notifier.Send("Hello!") // "SMS: Hello!"Ten wzorzec sprawdza się, gdy chcesz tworzyć obiekty na podstawie warunków czasu wykonania, scentralizować złożoną logikę inicjalizacji lub łatwo dodawać nowe typy bez modyfikowania kodu klienta. Wystarczy dodać nową strukturę implementującą interfejs i zaktualizować funkcję fabrykującą.
Wyzwanie
ŁatwyZbudujmy system konwerterów dokumentów z użyciem wzorca Fabryki! Utworzysz fabrykę, która tworzy różne konwertery dokumentów na podstawie formatu docelowego, dzięki czemu kod klienta może współpracować z dowolnym konwerterem za pośrednictwem ujednoliconego interfejsu.
Rozmieścisz kod w dwóch plikach:
converter.go: Zdefiniuj interfejs konwertera i jego konkretne implementacje.Utwórz interfejs
Converterz metodąConvert(content string) string, która przyjmuje treść dokumentu i zwraca przekonwertowany wynik.Zaimplementuj trzy typy konwerterów:
PDFConverter: jego metodaConvertzwracaPDF: [content]HTMLConverter: jego metodaConvertzwracaHTML: <p>[content]</p>MarkdownConverter: jego metodaConvertzwracaMD: # [content]
Utwórz funkcję fabrykującą
NewConverter(format string) Converter, która zwraca odpowiedni konwerter na podstawie ciągu formatu (pdf,htmllubmarkdown). W przypadku nierozpoznanego formatu zwróćPDFConverterjako domyślny.main.go: Użyj fabryki, aby utworzyć konwertery i przetwarzać dokumenty.Wczytaj typ formatu i treść dokumentu. Użyj fabryki, aby utworzyć odpowiedni konwerter, a następnie przekonwertuj treść i wyświetl wynik.
Dane wejściowe będą miały następującą postać:
- Wiersz 1: Typ formatu (
pdf,html,markdownlub inny) - Wiersz 2: Treść dokumentu do przekonwertowania
Na przykład dla danych:
html
Welcome to Go ProgrammingWynik powinien być następujący:
HTML: <p>Welcome to Go Programming</p>A dla danych:
markdown
Chapter OneWynik powinien być następujący:
MD: # Chapter OneA dla danych:
pdf
Annual Report 2024Wynik powinien być następujący:
PDF: Annual Report 2024A dla danych:
docx
Meeting NotesWynik powinien być następujący:
PDF: Meeting NotesZwróć uwagę, że kod główny nie musi znać konkretnych typów konwerterów. Po prostu prosi fabrykę o konwerter i korzysta z interfejsu. Dzięki temu można łatwo dodawać nowe formaty bez zmieniania kodu klienta!
Spróbuj swoich sił
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
// Odczytaj typ formatu
scanner.Scan()
format := scanner.Text()
// Odczytaj zawartość dokumentu
scanner.Scan()
content := scanner.Text()
// TODO: Użyj fabryki, aby utworzyć odpowiedni konwerter
// TODO: Przekonwertuj zawartość i wypisz wynik
fmt.Println(result)
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy OOP w Go
Pliki zewnętrzneObszar roboczy i moduły GoPakiety i importyNazwy eksportowane i nieeksportowaneWprowadzenie do OOP w GoStruktury jako klasyDefiniowanie metod dla strukturOdbiorniki wskaźnikowe i wartościoweInicjalizacja strukturFunkcje konstruktoraPodsumowanie – prosty kalkulator4Interfejsy
Wprowadzenie do interfejsówImplementacja niejawnaInterfejs jako kontraktPusty interfejs (any)Asercja typuPrzełącznik typówKompozycja interfejsówInterfejsy Stringer i ErrorPowtórka — kalkulator figur7Hermetyzacja
Pola eksportowane i nieeksportowaneHermetyzacja na poziomie pakietuMetody pobierające i ustawiająceUkrywanie informacji w GoPowtórka – dane studentów10Typy generyczne (Go 1.18+)
Wprowadzenie do typów generycznychParametry typówOgraniczenia typówStruktury generyczneObejście ograniczeń metod generycznychPodsumowanie — generyczna kolekcja13Wzorce projektowe — część 1
Wprowadzenie do wzorców projektowychWzorzec SingletonWzorzec FactoryWzorzec Abstract FactoryWzorzec ObserverWzorzec Strategy2Typy i struktury w praktyce
Typy proste i złożoneDefiniowanie własnych typówTagi pól strukturStruktury anonimoweStruktury zagnieżdżoneWartości zerowe i domyślnePodsumowanie – książka kontaktów5Kompozycja zamiast dziedziczenia
Dlaczego Go nie ma dziedziczeniaPodstawy osadzania strukturPromowanie metodOsadzanie wielu strukturOsadzanie a agregacjaPrzesłanianie osadzonych metodPodsumowanie — hierarchia pracowników8Obsługa błędów i programowanie obiektowe
Interfejs błęduWłasne typy błędówOpakowywanie błędów (fmt.Errorf)Błędy wartowniczeerrors.Is() i errors.As()Panic, Defer i RecoverPodsumowanie — parser plików3Wskaźniki i pamięć
Podstawy wskaźników w GoWskaźniki do strukturPrzekazywanie przez wartość a przez referencjęFunkcja new()Odśmiecanie pamięci w GoPowtórka — kreator listy wiązanej6Polimorfizm w Go
Polimorfizm za pomocą interfejsówDuck typing w GoZasady spełniania interfejsówKolekcje polimorficzneWstrzykiwanie zależnościPowtórka — procesor płatności9Współbieżność i OOP
Podstawy goroutinesKanały i komunikacjaKanały buforowane i niebuforowaneInstrukcja selectsync.Mutex i sync.RWMutexsync.WaitGroupProjektowanie struktur bezpiecznych wątkowoPowtórka – pula workerów12Zaawansowane zagadnienia programowania obiektowego
Wzorzec opcji funkcyjnychWzorzec Builder w GoŁańcuchowe wywoływanie metodAliasy typów a definicje typówPodstawy refleksjiPrzegląd generowania koduPoćwicz samodzielnie: Kompilator Go online