Autumn SALE
Metoda wytwórcza

Metoda wytwórcza w języku Go

Metoda wytwórcza jest kreacyjnym wzorcem projektowym rozwiązującym problem tworzenia obiektów-produktów bez określania ich konkretnych klas.

Metoda wytwórcza definiuje metodę która ma służyć tworzeniu obiektów bez bezpośredniego wywoływania konstruktora (poprzez operator new). Podklasy mogą nadpisać tę metodę w celu zmiany klasy tworzonych obiektów.

Jeśli masz problem ze zrozumieniem różnicy pomiędzy poszczególnymi koncepcjami i wzorcami wytwórczymi, przeczytaj nasze Porównanie fabryk.

Przykład koncepcyjny

W Go nie da się zaimplementować klasycznego wzorca Metody wytwórczej z racji braku takich funkcjonalności języków obiektowych jak klasy i dziedziczenie. Możemy jednak zaimplementować jego okrojoną wersję - Fabrykę Prostą.

W poniższym przykładzie będziemy produkować różne rodzaje broni stosując strukturę fabryczną.

Zaczniemy od stworzenia interfejsu iGun definiującego wszystkie metody właściwe broniom. Mamy typ struktury gun implementujący interfejs iGun. Dwie konkretne bronie — ak47 i muszkiet zawierają strukturę broni i pośrednio implementują wszystkie metody iGun.

Struktura gunFactory służy za fabrykę tworzącą bronie wybranego typu na podstawie przekazanego jej argumentu. Klientem jest tu main.go. Zamiast pracować bezpośrednio z ak47 lub z muszkietem, zależna jest od gunFactory w zakresie generowania instancji różnych typów broni zależnie od parametrów-łańcuchów znaków.

iGun.go: Interfejs produktu

package main

type IGun interface {
	setName(name string)
	setPower(power int)
	getName() string
	getPower() int
}

gun.go: Konkretny produkt

package main

type Gun struct {
	name  string
	power int
}

func (g *Gun) setName(name string) {
	g.name = name
}

func (g *Gun) getName() string {
	return g.name
}

func (g *Gun) setPower(power int) {
	g.power = power
}

func (g *Gun) getPower() int {
	return g.power
}

ak47.go: Konkretny produkt

package main

type Ak47 struct {
	Gun
}

func newAk47() IGun {
	return &Ak47{
		Gun: Gun{
			name:  "AK47 gun",
			power: 4,
		},
	}
}

musket.go: Konkretny produkt

package main

type musket struct {
	Gun
}

func newMusket() IGun {
	return &musket{
		Gun: Gun{
			name:  "Musket gun",
			power: 1,
		},
	}
}

gunFactory.go: Fabryka

package main

import "fmt"

func getGun(gunType string) (IGun, error) {
	if gunType == "ak47" {
		return newAk47(), nil
	}
	if gunType == "musket" {
		return newMusket(), nil
	}
	return nil, fmt.Errorf("Wrong gun type passed")
}

main.go: Kod klienta

package main

import "fmt"

func main() {
	ak47, _ := getGun("ak47")
	musket, _ := getGun("musket")

	printDetails(ak47)
	printDetails(musket)
}

func printDetails(g IGun) {
	fmt.Printf("Gun: %s", g.getName())
	fmt.Println()
	fmt.Printf("Power: %d", g.getPower())
	fmt.Println()
}

output.txt: Wynik działania

Gun: AK47 gun
Power: 4
Gun: Musket gun
Power: 1
Na podstawie: Golang By Example

Metoda wytwórcza w innych językach

Metoda wytwórcza w języku C# Metoda wytwórcza w języku C++ Metoda wytwórcza w języku Java Metoda wytwórcza w języku PHP Metoda wytwórcza w języku Python Metoda wytwórcza w języku Ruby Metoda wytwórcza w języku Rust Metoda wytwórcza w języku Swift Metoda wytwórcza w języku TypeScript