SOLDES de printemps
Fabrique abstraite

Fabrique abstraite en Go

La Fabrique abstraite est un patron de conception de création qui permet de créer des familles de produits complètes sans avoir à préciser leurs classes concrètes.

La fabrique abstraite définit une interface pour la création de chaque produit, mais délègue la véritable création des produits aux classes concrètes de la fabrique. Chaque type de fabrique correspond à une certaine variété de produits.

Le code client appelle les méthodes de création d’un objet Fabrique plutôt que de créer directement les produits à l’aide d’un constructeur (opérateur new). Comme chaque fabrique possède sa propre variante de produit, tous ses produits seront compatibles.

Le code client manipule les fabriques et les produits uniquement via leurs interfaces abstraites, ce qui lui permet de travailler avec n’importe quelle variante de produit créée par un objet Fabrique. Créez juste une nouvelle classe concrète Fabrique et passez-la au code client.

Lisez notre Comparaison des fabriques si vous avez du mal à comprendre la différence entre les divers concepts et patrons.

Exemple conceptuel

Prenons le cas où vous voulez acheter des affaires de sport et plus précisément un ensemble de deux produits : une paire de chaussures et un maillot. Vous aimeriez acquérir une tenue assortie de la même marque.

Pour transformer tout ceci en code, la fabrique abstraite va nous aider à créer des ensembles de produits qui seraient systématiquement assortis.

iSportsFactory.go: Interface de la fabrique abstraite

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: Fabrique concrète

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: Fabrique concrète

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: Produit abstrait

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: Produit concret

package main

type AdidasShoe struct {
	Shoe
}

nikeShoe.go: Produit concret

package main

type NikeShoe struct {
	Shoe
}

iShirt.go: Produit abstrait

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: Produit concret

package main

type AdidasShirt struct {
	Shirt
}

nikeShirt.go: Produit concret

package main

type NikeShirt struct {
	Shirt
}

main.go: Code client

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: Résultat de l’exécution

Logo: nike
Size: 14
Logo: nike
Size: 14
Logo: adidas
Size: 14
Logo: adidas
Size: 14

Fabrique abstraite dans les autres langues

Fabrique abstraite en C# Fabrique abstraite en C++ Fabrique abstraite en Java Fabrique abstraite en PHP Fabrique abstraite en Python Fabrique abstraite en Ruby Fabrique abstraite en Rust Fabrique abstraite en Swift Fabrique abstraite en TypeScript