Menu
Coddy logo textTech

Patron Abstract Factory

Fait partie de la section Programmation Orientée Objet du Journey GO de Coddy — leçon 88 sur 107.

Le pattern Abstract Factory étend le pattern Factory en créant des familles d'objets apparentés sans spécifier leurs types concrets. Au lieu d'une seule fonction de fabrique, vous définissez une interface de fabrique que plusieurs fabriques concrètes implémentent, chacune produisant un ensemble cohérent d'objets apparentés.

Considérez une boîte à outils d'interface utilisateur qui doit créer des boutons et des cases à cocher. Différents systèmes d'exploitation nécessitent des implémentations différentes, mais les composants doivent fonctionner ensemble de manière cohérente :

type Button interface {
    Render() string
}

type Checkbox interface {
    Check() string
}

// Interface de fabrique abstraite
type GUIFactory interface {
    CreateButton() Button
    CreateCheckbox() Checkbox
}

Chaque fabrique concrète produit une famille de composants apparentés :

// Famille Windows
type WindowsButton struct{}
func (w WindowsButton) Render() string { return "Windows Button" }

type WindowsCheckbox struct{}
func (w WindowsCheckbox) Check() string { return "Windows Checkbox" }

type WindowsFactory struct{}
func (w WindowsFactory) CreateButton() Button { return WindowsButton{} }
func (w WindowsFactory) CreateCheckbox() Checkbox { return WindowsCheckbox{} }

// Famille Mac
type MacButton struct{}
func (m MacButton) Render() string { return "Mac Button" }

type MacCheckbox struct{}
func (m MacCheckbox) Check() string { return "Mac Checkbox" }

type MacFactory struct{}
func (m MacFactory) CreateButton() Button { return MacButton{} }
func (m MacFactory) CreateCheckbox() Checkbox { return MacCheckbox{} }

Le code client travaille avec l'interface de la fabrique, tout en restant indépendant des implémentations concrètes :

func BuildUI(factory GUIFactory) {
    button := factory.CreateButton()
    checkbox := factory.CreateCheckbox()
    fmt.Println(button.Render(), checkbox.Check())
}

Utilisez Abstract Factory lorsque votre système doit fonctionner avec plusieurs familles de produits apparentés et que vous souhaitez vous assurer que les composants d'une même famille sont utilisés ensemble. C'est plus complexe qu'une simple Factory, ne l'utilisez donc que lorsque vous avez réellement besoin de gérer des familles de produits.

challenge icon

Défi

Facile

Construisons un système de magasin de meubles en utilisant le motif Abstract Factory ! Vous allez créer des usines qui produisent des familles d'articles de mobilier apparentés — chaque usine produit un style cohérent (Modern ou Vintage), garantissant que les chaises et les tables de la même usine s'accordent esthétiquement.

Vous organiserez votre code sur trois fichiers :

  • furniture.go : Définissez vos interfaces de produits et vos types de meubles concrets.

    Créez deux interfaces de produits :

    • Chair avec une méthode SitOn() string
    • Table avec une méthode PlaceItems() string

    Implémentez deux familles de meubles :

    • Famille Modern : ModernChair retourne "Sitting on a sleek modern chair" et ModernTable retourne "Placing items on a glass modern table"
    • Famille Vintage : VintageChair retourne "Sitting on an ornate vintage chair" et VintageTable retourne "Placing items on a wooden vintage table"
  • factory.go : Définissez votre interface d'usine abstraite et vos usines concrètes.

    Créez une interface FurnitureFactory avec deux méthodes :

    • CreateChair() Chair
    • CreateTable() Table

    Implémentez deux usines concrètes :

    • ModernFactory qui produit ModernChair et ModernTable
    • VintageFactory qui produit VintageChair et VintageTable

    Créez également une fonction GetFactory(style string) FurnitureFactory qui retourne l'usine appropriée en fonction du style ("modern" ou "vintage"). Utilisez ModernFactory par défaut pour les styles non reconnus.

  • main.go : Utilisez vos usines pour meubler des pièces.

    Créez une fonction FurnishRoom(factory FurnitureFactory) string qui utilise l'usine pour créer une chaise et une table, puis retourne une chaîne formatée montrant les deux actions sur des lignes séparées.

    Lisez une entrée de style, obtenez l'usine appropriée, meublez une pièce et affichez le résultat.

Les entrées suivantes seront fournies :

  • Ligne 1 : Style de meuble ("modern", "vintage", ou autre chose)

Par exemple, avec :

modern

Votre sortie devrait être :

Sitting on a sleek modern chair
Placing items on a glass modern table

Et avec :

vintage

Votre sortie devrait être :

Sitting on an ornate vintage chair
Placing items on a wooden vintage table

Et avec :

rustic

Votre sortie devrait être :

Sitting on a sleek modern chair
Placing items on a glass modern table

Remarquez comment la fonction FurnishRoom fonctionne avec n'importe quelle usine via l'interface — elle ne sait pas si elle crée des meubles modernes ou vintage. Cela garantit que tous les meubles d'une pièce proviennent de la même famille, maintenant ainsi un style cohérent !

Aide-mémoire

Le pattern Abstract Factory (ou Fabrique Abstraite) crée des familles d'objets apparentés sans spécifier leurs types concrets. Il définit une interface de fabrique que plusieurs fabriques concrètes implémentent, chacune produisant un ensemble cohérent d'objets apparentés.

Structure

Définissez des interfaces de produit pour chaque type d'objet :

type Button interface {
    Render() string
}

type Checkbox interface {
    Check() string
}

Créez une interface de fabrique abstraite qui déclare des méthodes pour créer chaque type de produit :

type GUIFactory interface {
    CreateButton() Button
    CreateCheckbox() Checkbox
}

Implémentations concrètes

Implémentez des familles de produits concrètes où chaque famille a un style ou un comportement cohérent :

// Famille Windows
type WindowsButton struct{}
func (w WindowsButton) Render() string { return "Windows Button" }

type WindowsCheckbox struct{}
func (w WindowsCheckbox) Check() string { return "Windows Checkbox" }

type WindowsFactory struct{}
func (w WindowsFactory) CreateButton() Button { return WindowsButton{} }
func (w WindowsFactory) CreateCheckbox() Checkbox { return WindowsCheckbox{} }

// Famille Mac
type MacButton struct{}
func (m MacButton) Render() string { return "Mac Button" }

type MacCheckbox struct{}
func (m MacCheckbox) Check() string { return "Mac Checkbox" }

type MacFactory struct{}
func (m MacFactory) CreateButton() Button { return MacButton{} }
func (m MacFactory) CreateCheckbox() Checkbox { return MacCheckbox{} }

Code client

Le code client travaille avec l'interface de la fabrique, restant indépendant des implémentations concrètes :

func BuildUI(factory GUIFactory) {
    button := factory.CreateButton()
    checkbox := factory.CreateCheckbox()
    fmt.Println(button.Render(), checkbox.Check())
}

Quand l'utiliser

Utilisez l'Abstract Factory lorsque votre système doit fonctionner avec plusieurs familles de produits apparentés et que vous souhaitez garantir que les composants d'une même famille sont utilisés ensemble. C'est plus complexe qu'une simple Factory, ne l'utilisez donc que lorsque vous avez réellement besoin de gérer des familles de produits.

Essayez vous-même

package main

import "fmt"

// FurnishRoom utilise une fabrique pour créer des meubles et retourne le résultat
// TODO: Implémenter cette fonction
// - Utiliser la fabrique pour créer une chaise et une table
// - Retourner une chaîne avec le résultat de SitOn() sur la première ligne et le résultat de PlaceItems() sur la deuxième ligne
func FurnishRoom(factory FurnitureFactory) string {
	// TODO: Créer une chaise et une table en utilisant la fabrique
	// TODO: Retourner une chaîne formatée avec les deux actions sur des lignes séparées
	return ""
}

func main() {
	var style string
	fmt.Scanln(&style)

	// TODO: Obtenir la fabrique appropriée en fonction du style
	// TODO: Meubler une pièce en utilisant la fabrique
	// TODO: Afficher le résultat
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation Orientée Objet