![Pont](/images/patterns/cards/bridge-mini.png?id=b389101d8ee8e23ffa1b534c704d0774)
Pont en Go
Le Pont est un patron de conception structurel qui scinde la logique métier ou divise de grandes classes dans des hiérarchies de classes séparées qui vont ensuite évoluer indépendamment.
Une de ces hiérarchies (souvent appelée l’abstraction) gardera une référence vers un objet de la seconde hiérarchie (l’implémentation). L’abstraction pourra déléguer certains (parfois la majorité) de ses appels aux objets de l’implémentation. Puisque toutes les implémentations ont une interface commune, elles sont interchangeables à l’intérieur de l’abstraction.
Exemple conceptuel
Prenons deux types d’ordinateurs : un sous Mac et un sous Windows. Prenons également deux types d’imprimantes : Epson et HP. Ces ordinateurs et imprimantes doivent pouvoir fonctionner ensemble dans toutes les combinaisons possibles. Le client ne veut pas s’occuper des détails de la connexion entre imprimantes et ordinateurs.
Si nous ajoutons de nouvelles imprimantes, nous ne voulons pas que notre code croisse exponentiellement. Plutôt que de créer quatre structs pour les 2 x 2 combinaisons, nous mettons en place deux hiérarchies :
- Une hiérarchie d’abstraction : pour nos ordinateurs.
- Une hiérarchie d’implémentation : pour nos imprimantes.
Ces deux hiérarchies communiquent ensemble via un pont, l’abstraction (ordinateur) gardant une référence vers l’implémentation (imprimante). L’abstraction et l’implémentation peuvent être développées indépendamment l’une de l’autre.
computer.go: Abstraction
package main
type Computer interface {
Print()
SetPrinter(Printer)
}
mac.go: Abstraction spécialisée
package main
import "fmt"
type Mac struct {
printer Printer
}
func (m *Mac) Print() {
fmt.Println("Print request for mac")
m.printer.PrintFile()
}
func (m *Mac) SetPrinter(p Printer) {
m.printer = p
}
windows.go: Abstraction spécialisée
package main
import "fmt"
type Windows struct {
printer Printer
}
func (w *Windows) Print() {
fmt.Println("Print request for windows")
w.printer.PrintFile()
}
func (w *Windows) SetPrinter(p Printer) {
w.printer = p
}
printer.go: Implémentation
package main
type Printer interface {
PrintFile()
}
epson.go: Implémentation concrète
package main
import "fmt"
type Epson struct {
}
func (p *Epson) PrintFile() {
fmt.Println("Printing by a EPSON Printer")
}
hp.go: Implémentation concrète
package main
import "fmt"
type Hp struct {
}
func (p *Hp) PrintFile() {
fmt.Println("Printing by a HP Printer")
}
main.go: Code client
package main
import "fmt"
func main() {
hpPrinter := &Hp{}
epsonPrinter := &Epson{}
macComputer := &Mac{}
macComputer.SetPrinter(hpPrinter)
macComputer.Print()
fmt.Println()
macComputer.SetPrinter(epsonPrinter)
macComputer.Print()
fmt.Println()
winComputer := &Windows{}
winComputer.SetPrinter(hpPrinter)
winComputer.Print()
fmt.Println()
winComputer.SetPrinter(epsonPrinter)
winComputer.Print()
fmt.Println()
}
output.txt: Résultat de l’exécution
Print request for mac
Printing by a HP Printer
Print request for mac
Printing by a EPSON Printer
Print request for windows
Printing by a HP Printer
Print request for windows