Autumn SALE
Абстрактна фабрика

Абстрактна фабрика на Go

Абстрактна фабрика — це породжуючий патерн проектування, який вирішує проблему створення цілих сімейств пов’язаних продуктів, без прив’язки коду до конкретних класів продуктів.

Абстрактна фабрика задає інтерфейс створення всіх доступних типів продуктів, а кожна конкретна реалізація фабрики породжує продукти однієї з варіацій. Клієнтський код викликає методи фабрики для отримання продуктів, замість самостійного створювання їх за допомогою оператора new. При цьому, фабрика сама стежить за тим, щоб створюваний продукт був потрібної варіації.

Концептуальний приклад

Уявімо, що вам потрібно купити спортивну форму, яка складається з двох різних речей: пара взуття і футболка. Ви хочете придбати повний комплект від одного бренду, щоб речі поєднувалися між собою.

Перекладаючи вищевказане у код, Абстрактна фабрика допоможе нам створювати набори продуктів, які завжди будуть підходити один до одного.

iSportsFactory.go: Інтерфейс абстрактної фабрики

package main

import "fmt"

type ISportsFactory interface {
	makeShoe() IShoe
	makeShirt() IShirt
}

func GetSportsFactory(brand string) (ISportsFactory, error) {
	if brand == "adidas" {
		return &Adidas{}, nil
	}

	if brand == "nike" {
		return &Nike{}, nil
	}

	return nil, fmt.Errorf("Wrong brand type passed")
}

adidas.go: Конкретна фабрика

package main

type Adidas struct {
}

func (a *Adidas) makeShoe() IShoe {
	return &AdidasShoe{
		Shoe: Shoe{
			logo: "adidas",
			size: 14,
		},
	}
}

func (a *Adidas) makeShirt() IShirt {
	return &AdidasShirt{
		Shirt: Shirt{
			logo: "adidas",
			size: 14,
		},
	}
}

nike.go: Конкретна фабрика

package main

type Nike struct {
}

func (n *Nike) makeShoe() IShoe {
	return &NikeShoe{
		Shoe: Shoe{
			logo: "nike",
			size: 14,
		},
	}
}

func (n *Nike) makeShirt() IShirt {
	return &NikeShirt{
		Shirt: Shirt{
			logo: "nike",
			size: 14,
		},
	}
}

iShoe.go: Абстрактний продукт

package main

type IShoe interface {
	setLogo(logo string)
	setSize(size int)
	getLogo() string
	getSize() int
}

type Shoe struct {
	logo string
	size int
}

func (s *Shoe) setLogo(logo string) {
	s.logo = logo
}

func (s *Shoe) getLogo() string {
	return s.logo
}

func (s *Shoe) setSize(size int) {
	s.size = size
}

func (s *Shoe) getSize() int {
	return s.size
}

adidasShoe.go: Конкретний продукт

package main

type AdidasShoe struct {
	Shoe
}

nikeShoe.go: Конкретний продукт

package main

type NikeShoe struct {
	Shoe
}

iShirt.go: Абстрактний продукт

package main

type IShirt interface {
	setLogo(logo string)
	setSize(size int)
	getLogo() string
	getSize() int
}

type Shirt struct {
	logo string
	size int
}

func (s *Shirt) setLogo(logo string) {
	s.logo = logo
}

func (s *Shirt) getLogo() string {
	return s.logo
}

func (s *Shirt) setSize(size int) {
	s.size = size
}

func (s *Shirt) getSize() int {
	return s.size
}

adidasShirt.go: Конкретний продукт

package main

type AdidasShirt struct {
	Shirt
}

nikeShirt.go: Конкретний продукт

package main

type NikeShirt struct {
	Shirt
}

main.go: Клієнтський код

package main

import "fmt"

func main() {
	adidasFactory, _ := GetSportsFactory("adidas")
	nikeFactory, _ := GetSportsFactory("nike")

	nikeShoe := nikeFactory.makeShoe()
	nikeShirt := nikeFactory.makeShirt()

	adidasShoe := adidasFactory.makeShoe()
	adidasShirt := adidasFactory.makeShirt()

	printShoeDetails(nikeShoe)
	printShirtDetails(nikeShirt)

	printShoeDetails(adidasShoe)
	printShirtDetails(adidasShirt)
}

func printShoeDetails(s IShoe) {
	fmt.Printf("Logo: %s", s.getLogo())
	fmt.Println()
	fmt.Printf("Size: %d", s.getSize())
	fmt.Println()
}

func printShirtDetails(s IShirt) {
	fmt.Printf("Logo: %s", s.getLogo())
	fmt.Println()
	fmt.Printf("Size: %d", s.getSize())
	fmt.Println()
}

output.txt: Результат виконання

Logo: nike
Size: 14
Logo: nike
Size: 14
Logo: adidas
Size: 14
Logo: adidas
Size: 14
На основі: Golang By Example

Абстрактна фабрика іншими мовами програмування

Абстрактна фабрика на C# Абстрактна фабрика на C++ Абстрактна фабрика на Java Абстрактна фабрика на PHP Абстрактна фабрика на Python Абстрактна фабрика на Ruby Абстрактна фабрика на Rust Абстрактна фабрика на Swift Абстрактна фабрика на TypeScript