桥接(Bridge)模式是一种结构型设计模式, 可将一个大类或一系列紧密相关的类拆分为抽象和实现两个独立的层次结构, 从而能在开发时分别使用。
桥接模式的理念就是:“将抽象与实现解耦,将不同类别的继承关系改为关联关系。 ”
桥接模式建议将一个较大的类拆分成两中角色。
- 抽象角色 - 抽象角色是一个接口。它的子类也被称为修正抽象角色。抽象角色包含一个对实现角色的引用。
- 实现角色 - 实现角色也是一个接口。实现角色的子类被称为具化实现角色。
这样分层的优势在于在调用抽象角色的时候不需要考虑实现层的内容。
举个例子,假设我们手上有两部笔记本:Mac本和Windows本;同时也有两部打印机:爱普生(Epson)打印机和惠普(Hp)打印机。我们希望笔记本和打印机能任意组合来完成工作,用户只通过笔记本进行操作而无需关心打印机是如何工作的。
这个例子中有2×2四种组合,如果再分别增加Linux本和联想打印机,将需要提供9种方法。但是如果采用桥接模式则不需要为此创建四个struct,而是创建两层:
- 抽象层
- 实现层
抽象层(这里是computer)和实现层(这里是printer)通过抽象层中对实现层的引用来进行交互,这个引用就是桥接模式所谓的桥梁。通过桥接模式,抽象层和引用层可以分别独立实现而不互相影响。
代码示例:
package main
import "fmt"
// 抽象角色
type computer interface {
print()
setPrinter(printer)
}
// 修正抽象角色1
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
}
// 修正抽象角色2
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
}
// 实现角色
type printer interface {
printFile()
}
// 具体实现角色1
type epson struct {
}
func (p *epson) printFile() {
fmt.Println("Printing by a EPSON Printer")
}
// 具体实现角色2
type hp struct {
}
func (p *hp) printFile() {
fmt.Println("Printing by a HP Printer")
}
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()
}
运行示例,输出结果:
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
参考文章: