1. Co to jest wzorzec metody fabrycznej

Wzorzec metody fabrycznej to kreacyjny wzorzec projektowy, który dostarcza sposób na skapsułkowanie procesu tworzenia obiektów w podklasach. W ten sposób klient może tworzyć obiekty, wywołując metodę fabryczną, nie martwiąc się o konkretny proces tworzenia obiektów.

2. Charakterystyka i Zalety wzorca metody fabrycznej

Charakterystyka wzorca metody fabrycznej obejmuje:

  • Odseparowanie tworzenia i użycia obiektów, gdzie klient musi dbać tylko o metodę fabryczną i abstrakcyjny interfejs produktu.
  • System może być rozwijany poprzez dodanie nowych konkretncyh klas fabrycznych i konkretnych klas produktów, zgodnie z zasadą otwarte/zamknięte.

Zalety wzorca metody fabrycznej obejmują:

  • Skapsułkowanie procesu tworzenia obiektów, co sprawia, że system staje się bardziej elastyczny i rozszerzalny.
  • Ukrywanie szczegółów implementacyjnych konkretnych klas produktów, zmniejszając zależność klienta i sprzężenie do konkretnych klas.
  • Zapewnienie standaryzowanego sposobu tworzenia produktów, ułatwiając konserwację i rozszerzanie systemu.

3. Scenariusze zastosowania wzorca metody fabrycznej

Wzorzec metody fabrycznej nadaje się do następujących scenariuszy:

  • Klient nie jest uzależniony od konkretnych klas produktów, ale od abstrakcyjnego interfejsu produktu.
  • Klient potrzebuje dynamicznie tworzyć różne obiekty produktów w oparciu o różne warunki.
  • Potrzeba skapsułkowania i ukrycia procesu tworzenia obiektu produktu.

4. Implementacja wzorca metody fabrycznej w języku Golang

4.1 Diagram klas UML

Wzorzec metody fabrycznej w języku Golang

4.2 Implementacja krok 1: Zdefiniowanie abstrakcyjnego interfejsu produktu

package factory

// Produkt to abstrakcyjny interfejs produktu
type Produkt interface {
	Operacja() string
}

4.3 Implementacja krok 2: Tworzenie klas implementacji konkretnej produktu

package factory

// KonkretnyProduktA to klasa konkretnego produktu A
type KonkretnyProduktA struct{}

// Operacja to metoda klasy konkretnego produktu A
func (p *KonkretnyProduktA) Operacja() string {
	return "KonkretnyProduktA"
}

// KonkretnyProduktB to klasa konkretnego produktu B
type KonkretnyProduktB struct{}

// Operacja to metoda klasy konkretnego produktu B
func (p *KonkretnyProduktB) Operacja() string {
	return "KonkretnyProduktB"
}

4.4 Implementacja krok 3: Zdefiniowanie abstrakcyjnego interfejsu fabryki

package factory

// Fabryka to abstrakcyjny interfejs fabryki
type Fabryka interface {
	TworzProdukt() Produkt
}

4.5 Implementacja krok 4: Tworzenie klas implementacji konkretnej fabryki

package factory

// KonkretnaFabrykaA to klasa konkretnej fabryki A
type KonkretnaFabrykaA struct{}

// TworzProdukt to metoda klasy konkretnej fabryki A
func (f *KonkretnaFabrykaA) TworzProdukt() Produkt {
	return &KonkretnyProduktA{}
}

// KonkretnaFabrykaB to klasa konkretnej fabryki B
type KonkretnaFabrykaB struct{}

// TworzProdukt to metoda klasy konkretnej fabryki B
func (f *KonkretnaFabrykaB) TworzProdukt() Produkt {
	return &KonkretnyProduktB{}
}

4.6 Implementacja krok 5: Klient wywołuje metodę fabryczną w celu tworzenia obiektów produktu

package main

import (
	"fmt"
	"github.com/your/package/factory"
)

func main() {
	// Utwórz Konkretną Fabrykę A
	fabrykaA := &factory.KonkretnaFabrykaA{}
	// Wywołaj metodę fabryczną w celu stworzenia obiektów produktu
	produktA := fabrykaA.TworzProdukt()
	fmt.Println(produktA.Operacja())

	// Utwórz Konkretną Fabrykę B
	fabrykaB := &factory.KonkretnaFabrykaB{}
	// Wywołaj metodę fabryczną w celu stworzenia obiektów produktu
	produktB := fabrykaB.TworzProdukt()
	fmt.Println(produktB.Operacja())
}

W powyższym kodzie definiujemy abstrakcyjny interfejs produktu Produkt oraz konkretne klasy produktów KonkretnyProduktA i KonkretnyProduktB. Następnie definiujemy abstrakcyjny interfejs fabryki Fabryka oraz konkretne klasy fabryki KonkretnaFabrykaA i KonkretnaFabrykaB. Klient może tworzyć konkretne obiekty produktów, wywołując metodę fabryczną klasy konkretnej fabryki, realizując tym samym wzorzec metody fabrycznej.

Dzięki powyższym krokom zakończyliśmy implementację wzorca metody fabrycznej w języku Golang. Ten sposób odseparowuje klienta od konkretnych klas produktów, pozwalając klientowi skupić się tylko na abstrakcyjnym interfejsie produktu. Tym samym szczegóły implementacyjne konkretnych klas produktów są skapsułkowane w klasie konkretnej fabryki, sprawiając że system staje się bardziej elastyczny i rozszerzalny. Wzorzec metody fabrycznej jest bardzo powszechny w praktyce, zwłaszcza w scenariuszach, w których potrzebne jest dynamiczne tworzenie różnych typów obiektów, co skutecznie poprawia użyteczność i konserwowalność kodu.