Friend spotlight!
Whimsical Animations course
Friend spotlight!
NEW Whimsical Animations course
Friend spotlight! NEW Whimsical Animations course
huge discount only this week
Friend spotlight! Want to make your project stand out? NEW Whimsical Animations course huge discount only this week
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

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