Bridge Design Pattern

桥接模式(Bridge Design Pattern)是一种结构型设计模式。意图将抽象和实现解耦,让它们独立变化

这里的抽象实现并非编程语言中的抽象元素(Interface)和具体元素(Struct),而是业务逻辑层面的抽象与实现。 拿给业务系统接入数据库中间件这个需求来说,任何一个编程语言都会抽象出一个库,它来对接具体的某个数据库驱动,并封装一组对 SQL 相关的操作。

比如 Go 语言标准库 database/sql 这个库便是一个“抽象”,而具体的数据库驱动库便是“实现”。 sql 库和 driver 库通过对象之间的组合,组装在一起。sql 的所有逻辑操作,最终委托给 driver 来执行。

UML Diagram

image

Example

Question:

需要将 N 个不同品牌计算机对接 M 个不同品牌的打印机

Code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package main

import "fmt"

// 抽象
type computer interface {
	print()
	setPrinter(printer)
}

// 精确抽象
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 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
}

// 实施
type printer interface {
	printFile()
}

// 具体实施
type epson struct{}

func (p *epson) printFile() {
	fmt.Println("Printing by a EPSON Printer")
}

// 具体实施
type hp struct{}

func (p *hp) printFile() {
	fmt.Println("Printing by a HP Printer")
}

// 客户端调用
func main() {
	macComputer := &mac{}
	macComputer.setPrinter(&hp{})
	macComputer.print()
	fmt.Println()

	macComputer.setPrinter(&epson{})
	macComputer.print()
	fmt.Println()

	winComputer := &windows{}
	winComputer.setPrinter(&hp{})
	winComputer.print()
	fmt.Println()

	winComputer.setPrinter(&epson{})
	winComputer.print()
	fmt.Println()
}

Output:

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
Printing by a EPSON Printer

Application Scenarios

  1. 希望拆分或重组一个具有多重功能的庞杂类,例如 database/sql 与 drivers
  2. 希望在几个独立维度上扩展一个类。例如 example

References

https://time.geekbang.org/column/article/202786

https://golangbyexample.com/bridge-design-pattern-in-go/