
Bridge en Go
Bridge es un patrón de diseño estructural que divide la lógica de negocio o una clase muy grande en jerarquías de clases separadas que se pueden desarrollar independientemente.
Una de estas jerarquías (a menudo denominada Abstracción) obtendrá una referencia a un objeto de la segunda jerarquía (Implementación). La abstracción podrá delegar algunas (en ocasiones, la mayoría) de sus llamadas al objeto de las implementaciones. Como todas las implementaciones tendrán una interfaz común, serán intercambiables dentro de la abstracción.
Ejemplo conceptual
Digamos que tienes dos tipos de computadora: Mac y Windows. También, dos tipos de impresora: Epson y HP. Todas las computadoras e impresoras deben funcionar unas con otras en cualquier combinación. El cliente no quiere preocuparse de los detalles de conectar impresoras a computadoras.
Si introducimos nuevas impresoras, no queremos que nuestro código crezca exponencialmente. En lugar de crear cuatro estructuras para la combinación 2*2, creamos dos jerarquías:
- Jerarquía de abstracción: éstas serán nuestras computadoras.
- Jerarquía de implementación: éstas serán nuestras impresoras.
Estas dos jerarquías se comunican entre sí a través de un Bridge, donde la Abstracción (computadora) contiene una referencia a la Implementación (impresora). Tanto la abstracción como la implementación pueden desarrollarse independientemente sin afectar la una a la otra.
computer.go: Abstracción
package main
type Computer interface {
Print()
SetPrinter(Printer)
}
mac.go: Abstracción refinada
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: Abstracción refinada
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: Implementación
package main
type Printer interface {
PrintFile()
}
epson.go: Implementación concreta
package main
import "fmt"
type Epson struct {
}
func (p *Epson) PrintFile() {
fmt.Println("Printing by a EPSON Printer")
}
hp.go: Implementación concreta
package main
import "fmt"
type Hp struct {
}
func (p *Hp) PrintFile() {
fmt.Println("Printing by a HP Printer")
}
main.go: Código cliente
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: Resultado de la ejecución
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