桥接模式是一种结构型设计模式,通过桥接模式可以将抽象部分和它的实现部分分离。这看着有点儿奇怪,接下来会作详细说明。

桥接模式建议将一个较大的类拆分成两中角色。

  • 抽象角色 - 抽象角色是一个接口。它的子类也被称为修正抽象角色。抽象角色包含一个对实现角色的引用。
  • 实现角色 - 实现角色也是一个接口。实现角色的子类被称为具化实现角色。

这样分层的优势在于在调用抽象角色的时候不需要考虑实现层的内容。

举个例子,假设我们手上有两部笔记本:Mac本和Windows本;同时也有两部打印机:爱普生(Epson)打印机和惠普(Hp)打印机。我们希望笔记本和打印机能任意组合来完成工作,用户只通过笔记本进行操作而无需关心打印机是如何工作的。

这个例子中有2×2四种组合,但是不需要为此创建四个struct,而是创建两层:

  • 抽象层
  • 实现层

看下下面的图。在图中可以看到抽象层(这里是computer)和实现层(这里是printer)通过抽象层中对实现层的引用来进行交互,这个引用就是桥接模式所谓的桥梁。通过桥接模式,抽象层和引用层可以分别独立实现而不互相影响。

注意图中win和mac是如何嵌入printer的引用的:这里绑定的是printer接口,而非是priter的具体实现。这样就可以在运行时修改printer的值。如前面所说,printer引用在这里扮演了一个桥梁的角色,并实现了computer和printer的松耦合。

桥接模式的UML图如下:

接下来是前面的例子的代码。

抽象角色,computer.go:

type computer interface {

	print()

	setPrinter(printer)
}

修正抽象角色1,win.go

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
}

修正抽象角色2,mac.go

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
}

实现角色,printer.go

type printer interface {
printFile()
}

具体实现角色1,epson.go

import "fmt"

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

具体实现角色2,hp.go

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

Client, main.go

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

代码已上传至GitHub: zhyea / go-patterns / bridge-pattern

END!

GoLang设计模式19 - 桥接模式的更多相关文章

  1. 乐在其中设计模式(C#) - 桥接模式(Bridge Pattern)

    原文:乐在其中设计模式(C#) - 桥接模式(Bridge Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 桥接模式(Bridge Pattern) 作者:webabcd 介绍 ...

  2. Golang设计模式—简单工厂模式(Simple Factory Pattern)

    Golang设计模式--简单工厂模式 背景 假设我们在做一款小型翻译软件,软件可以将德语.英语.日语都翻译成目标中文,并显示在前端. 思路 我们会有三个具体的语言翻译结构体,或许以后还有更多,但现在分 ...

  3. java面试题之----jdbc中使用的设计模式(桥接模式)

    1.JDBC(JavaDatabase Connectivity) JDBC是以统一方式访问数据库的API. 它提供了独立于平台的数据库访问,也就是说,有了JDBC API,我们就不必为访问Oracl ...

  4. php设计模式之桥接模式

    php设计模式之桥接模式 一.概述 桥接模式:将两个原本不相关的类结合在一起,然后利用两个类中的方法和属性,输出一份新的结果. 其实就是讲不相关的东西通过类(本例中是SendInfo)结合在一起,从而 ...

  5. java设计模式7——桥接模式

    java设计模式7--桥接模式 1.桥接模式介绍 桥接模式是将抽象部分与它的实现部分分离,使他们都可以独立的变化.它是一种对象结构型模式,又称为柄体模式或接口模式. 2.解决问题 2.1.将复杂的组合 ...

  6. C++设计模式-Bridge桥接模式

    作用:将抽象部份与它的实现部份分离,使它们都可以独立地变化. 将抽象(Abstraction)与实现(Implementation)分离,使得二者可以独立地变化. 桥接模式号称设计模式中最难理解的模式 ...

  7. 设计模式之桥接模式(Bridge)

    注:本文不属于原创,而是根据原文重新整理,原文是:我给媳妇解释设计模式:第一部分 设计模式不是基于理论发明的.相反,总是先有问题场景,再基于需求和情景不断演化设计方案,最后把一些方案标准化成“模式”. ...

  8. 【GOF23设计模式】桥接模式

    来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_桥接模式.多层继承结构.银行日志管理.管理系统消息管理.人力资源的奖金计算  未用桥接模式: package com.te ...

  9. js设计模式(3)---桥接模式

    0.前言 看设计模式比较痛苦,一则是自己经验尚浅,不能体会到使用这些设计模式的益处:二则是不能很好把握使用这些设计模式的时机.所以这一部分看得断断续续,拖拖拉拉,为了了却这快心病,决定最近一口气看完几 ...

随机推荐

  1. Redis学习推荐资料合集

    目录 一.官方 二.书籍 三.推荐博客 一.官方 redis官网 redis中文网 redis中文命令网 redis模块 redis-github源码 redis报告 二.书籍 <Redis开发 ...

  2. 软件开发生命周期(SDLC)

    一.简介 软件开发生命周期又叫做 SDLC(Software Development Life Cycle),它是集合了计划.开发.测试和部署过程的集合.如下图所示 : 二.五个阶段 1.分析阶段: ...

  3. pipeline脚本管理

    目录 一.代码仓库 二.远程拉取 一.代码仓库 1.使用gitlab做pipeline脚本的存储,新建一个仓库 2.新建文件,把代码放进去 脚本名可以按照规律填写,环境_应用名_类型,例如:test_ ...

  4. Excel如何使用vlookup

    一.vlookup的语法 VLOOKUP (lookup_value, table_array, col_index_num, [range_lookup]) ①Lookup_value为需要在数据表 ...

  5. 逻辑判断(Power Query 之 M 语言)

    逻辑真:true 逻辑假:false 与函数:and true and true,结果为TRUE true and false,结果为FALSE false and false,结果为FALSE 或函 ...

  6. bootstrap.css 进度条没有动画效果

    操作系统设置会影响浏览器的行为 Win+R 输入 sysdm.cpl ,3 打开 性能 的 设置 确保 窗口内动画控件和元素 被勾选

  7. Django把现在时间写入数据库,模板渲染在页面中

    1. 导入time模块 import time 2. 获取现在时间,使用"年-月-日 时:分:秒"这样的模板,赋值给变量 在views.py中: pt = time.strftim ...

  8. CF803B Distances to Zero 题解

    Content 有一个长度为 \(n\) 的序列 \(a_1,a_2,a_3,...,a_n\),求每个数与它最近的 \(0\) 的距离(\(0\) 的距离为 \(0\)). 数据范围:\(1\leq ...

  9. 遍历显示自定义的widget

    需求 列表展示: 列表项都是同一格式,列表项数据从List里取 解决方案 使用map map源码 Iterable<T> map<T>(T f(E e)) => Mapp ...

  10. SpringBoot简单整合Gateway网关

    引入依赖 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>s ...