SOLDES de printemps
Pont

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

Pont dans les autres langues

Pont en C# Pont en C++ Pont en Java Pont en PHP Pont en Python Pont en Ruby Pont en Rust Pont en Swift Pont en TypeScript