
Fabrique en Go
La Fabrique est un patron de conception de création qui permet de créer des produits sans avoir à préciser leurs classes concrètes.
La fabrique définit une méthode qui doit être utilisée pour créer des objets à la place de l’appel au constructeur (opérateur new
). Les sous-classes peuvent redéfinir cette méthode pour modifier la classe des objets qui seront créés.
Lisez notre Comparaison des fabriques si vous avez du mal à saisir la différence entre les divers concepts et patrons.
Exemple conceptuel
Le patron de conception fabrique classique ne peut pas être implémenté en Go dû à l’absence de fonctionnalités POO comme les classes et l’héritage. Ceci étant, nous pouvons tout de même implémenter la version basique du patron, la fabrique simple.
Dans cet exemple, nous allons construire différents types d’armes à feu en utilisant une struct fabrique.
Tout d’abord, nous créons l’interface iGun
qui définit les méthodes que n’importe quelle arme à feu devrait avoir. Une struct gun
implémente l’interface iGun. Deux armes à feu concrètes (ak47
et musket
) sont imbriquées dans la struct gun et implémentent indirectement toutes les méthodes de iGun
.
La struct gunFactory
sert de fabrique qui crée des armes à feu du type demandé en fonction de l’argument fourni. main.go sert de client. Il repose sur gunFactory
pour créer des instances des différentes armes à feu au lieu d’interagir directement avec ak47
ou musket
et n’utilise que des paramètres sous forme de chaînes de caractère pour contrôler la production.
iGun.go: Interface produit
package main
type IGun interface {
setName(name string)
setPower(power int)
getName() string
getPower() int
}
gun.go: Produit concret
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: Produit concret
package main
type Ak47 struct {
Gun
}
func newAk47() IGun {
return &Ak47{
Gun: Gun{
name: "AK47 gun",
power: 4,
},
}
}
musket.go: Produit concret
package main
type musket struct {
Gun
}
func newMusket() IGun {
return &musket{
Gun: Gun{
name: "Musket gun",
power: 1,
},
}
}
gunFactory.go: Fabrique
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: Code client
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: Résultat de l’exécution
Gun: AK47 gun
Power: 4
Gun: Musket gun
Power: 1