结构型模式-桥接模式

什么是桥接模式

桥接是一种结构型设计模式, 可将一个大类或一系列紧密  相关的类拆分为抽象和实现  两个独立的层次结构,从而 能在开发时分别使用。

  1. 抽象部分(Abstraction)提供高层控制逻辑,依赖于完成底 层实际工作的实现对象。
  2. . 实现部分(Implementation)为所有具体实现声明通用接口。 抽象部分仅能通过在这里声明的方法与实现对象交互。抽象部分可以列出和实现部分一样的方法,但是抽象部分通 常声明一些复杂行为,这些行为依赖于多种由实现部分声明 的原语操作
  3. 具体实现(Concrete Implementations)中包括特定于平台的代码
  4. 精确抽象(Refined Abstraction)提供控制逻辑的变体。与其父类一样,它们通过通用实现接口与不同的实现进行交互
  5. 通常情况下,客户端(Client)仅关心如何与抽象部分合作。 但是,客户端需要将抽象对象与一个实现对象连接起来

Example

抽象

package main

type Computer interface {
Print()
SetPrinter(Printer)
}

精准抽象a

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
}

精准抽象b

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
}

实施

package main

type Printer interface {
PrintFile()
}

具体实施a

package main

import "fmt"

type Epson struct {
}

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

具体实施b

package main

import "fmt"

type Hp struct {
}

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

客户端

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()
}

适用场景

  1. 如果你想要拆分或重组一个具有多重功能的庞杂类(例如能 与多个数据库服务器进行交互的类),可以使用桥接模式。
  • 类的代码行数越多,弄清其运作方式就越困难,对其进行修 改所花费的时间就越长。一个功能上的变化可能需要在整个 类范围内进行修改,而且常常会产生错误,甚至还会有一些 严重的副作用
  1. 如果你希望在几个独立维度上扩展一个类,可使用该模式
  • 桥接建议将每个维度抽取为独立的类层次。初始类将相关工 作委派给属于对应类层次的对象,无需自己完成所有工作
  1. 如果你需要在运行时切换不同实现方法,可使用桥接模式
  • 当然并不是说一定要实现这一点,桥接模式可替换抽象部分 中的实现对象,具体操作就和给成员变量赋新值一样简单

优缺点

优点

  • 可以创建与平台无关的类和程序
  • 客户端代码仅与高层抽象部分进行互动,不会接触到平台的 详细信息
  • 开闭原则。你可以新增抽象部分和实现部分,且它们之间不 会相互影响
  • 单一职责原则。抽象部分专注于处理高层逻辑,实现部分处 理平台细节

缺点

  • 对高内聚的类使用该模式可能会让代码更加复杂

与其他模式的关系

  • 桥接通常会于开发前期进行设计,使你能够将程序的各个部 分独立开来以便开发。另一方面,适配器通常在已有程序中 使用,让相互不兼容的类能很好地合作
  • 桥接、状态和策略(在某种程度上包括适配器)模式的接口 非常相似。实际上,它们都基于组合模式——即将工作委派 给其他对象,不过也各自解决了不同的问题。模式并不只是 以特定方式组织代码的配方,你还可以使用它们来和其他开 发者讨论模式所解决的问题。
  • 你可以将抽象工厂和桥接搭配使用。如果由桥接定义的抽象 只能与特定实现合作,这一模式搭配就非常有用。在这种情 况下,抽象工厂可以对这些关系进行封装,并且对客户端代 码隐藏其复杂性
  • 你可以结合使用生成器和桥接模式: 主管类负责抽象工作, 各种不同的生成器负责实现工作。