结构型 - 2. 桥接模式

195 阅读2分钟

1. 原理解析

桥接模式,也叫作桥梁模式,英文是 Bridge Design Pattern。可将一个大类或一系列紧密相关的类拆分为抽象和实现两个独立的层次结构, 从而能在开发时分别使用。这个模式有两种不同的理解方式:

1.1 理解方式一

将抽象和实现解耦,让它们可以独立变化。

Decouple an abstraction from its implementation so that the two can vary independently.

定义中的“抽象”,指的并非“抽象类”或“接口”,而是被抽象出来的一套“类库”,它只包含骨架代码,真正的业务逻辑需要委派给定义中的“实现”来完成。而定义中的“实现”,也并非“接口的实现类”,而是一套独立的“类库”。“抽象”和“实现”独立开发,通过对象之间的组合关系,组装在一起

1.2 理解方式二

一个类存在两个(或多个)独立变化的维度,我们通过组合的方式,让这两个(或多个)维度可以独立进行扩展。

非常类似之前讲过的“组合优于继承”设计原则,通过组合关系来替代继承关系,避免继承层次的指数级爆炸。

桥接就是面向接口编程的集大成者。面向接口编程只是说在系统的某一个功能上将接口和实现解藕,而桥接是详细的分析系统功能,将各个独立的纬度都抽象出来,使用时按需组合。

2. 应用场景

2.1 拆分或重组一个具有多重功能的庞杂类

桥接模式可以将庞杂类拆分为几个类层次结构。此后,你可以修改任意一个类层次结构而不会影响到其他类层次结构。这种方法可以简化代码的维护工作,并将修改已有代码的风险降到最低。

2.2 独立维度上扩展一个类

桥接建议将每个维度抽取为独立的类层次。初始类将相关工作委派给属于对应类层次的对象,无需自己完成所有工作。

3. 代码实现

type Computer interface {
	print()
	setPrinter(printer Printer)
}

type mac struct {
	printer Printer
}

func (m *mac) print() {
	fmt.Println("Print request for mac")
	m.printer.printFile()
}

func (m *mac) setPrinter(printer Printer) {
	m.printer = printer
}

type windows struct {
	printer Printer
}

func (w *windows) print() {
	fmt.Println("Print request for windows")
	w.printer.printFile()
}

func (w *windows) setPrinter(printer Printer) {
	w.printer = printer
}


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 TestComputer(t *testing.T) {
	hpPrinter := &hp{}
	epsonPrinter := &epson{}
	macComputer := &mac{}
	macComputer.setPrinter(hpPrinter)
	macComputer.print()
	t.Log()
	macComputer.setPrinter(epsonPrinter)
	macComputer.print()
	t.Log()
	winComputer := &windows{}
	winComputer.setPrinter(hpPrinter)
	winComputer.print()
	t.Log()
	winComputer.setPrinter(epsonPrinter)
	winComputer.print()
	t.Log()
}