![Міст](/images/patterns/cards/bridge-mini.png?id=b389101d8ee8e23ffa1b534c704d0774)
Міст на Go
Міст — це структурний патерн, який розділяє бізнес-логіку або великий клас на кілька окремих ієрархій, які можна розвивати далі окремо одну від одної.
Одна з цих ієрархій (абстракція) отримає посилання на об’єкти іншої ієрархії (реалізація) і буде делегувати їм основну роботу. Завдяки тому, що всі реалізації будуть дотримуватись спільного інтерфейсу, їх можна буде взаємозамінювати всередині абстракції.
Концептуальний приклад
Уявімо, що у вас є два типи комп’ютерів: Mac і Windows, а також два типи принтерів: Epson і HP. Комп’ютери та принтери мусять працювати між собою у будь-яких комбінаціях. Клієнт не хоче думати про особливості підключення принтерів до комп’ютерів.
Ми не хочемо, щоб при введенні в цю систему нових принтерів кількість коду збільшувалася по експоненті. Замість створення чотирьох структур для 2 × 2 комбінацій, ми створимо дві ієрархії:
- Ієрархія абстракції: сюди будуть входити наші комп’ютери
- Ієрархія реалізації: сюди будуть входити наші принтери
Ці дві ієрархії спілкуються між собою за допомогою Моста, в якому Абстракція (комп’ютер) містить посилання на Реалізацію (принтер). І абстракцію, і реалізацію можна розробляти окремо, не впливаючи одне на одного.
computer.go: Абстракція
package main
type Computer interface {
Print()
SetPrinter(Printer)
}
mac.go: Розширена абстракція
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: Розширена абстракція
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: Реалізація
package main
type Printer interface {
PrintFile()
}
epson.go: Конкретна реалізація
package main
import "fmt"
type Epson struct {
}
func (p *Epson) PrintFile() {
fmt.Println("Printing by a EPSON Printer")
}
hp.go: Конкретна реалізація
package main
import "fmt"
type Hp struct {
}
func (p *Hp) PrintFile() {
fmt.Println("Printing by a HP Printer")
}
main.go: Клієнтський код
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: Результат виконання
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