结构型模式:桥接模式
文章首发: 结构型模式:桥接模式
七大结构型模式之二:桥接模式。
简介
姓名 :桥接模式
英文名 :Bridge Pattern
价值观 :解耦靠我
个人介绍 : Decouple an abstraction from its implementation so that the two can vary independently. 将抽象和实现解耦,使得两者可以独立地变化。 (来自《设计模式之禅》)
你要的故事
现在手机二分天下,安卓手机和苹果手机目前占有率高居 98.45%,其中安卓手机占有率为 70.21%,苹果手机占有率为 28.24%,如下图所示。
(数据从 netmarketshare 来)
因为有这 2 个系统,所以很多软件商都不得不开发 2 个系统的 APP。我们就拿这个案例来讲,目前手机有安卓手机和苹果手机,软件有谷歌浏览器和火狐浏览器,通过手机打开软件这一过程来讲讲桥接模式。
从个人介绍可见,需要抽象化和实现化,然后使用桥接模式将抽象和实现解耦。
抽象化
:把一类对象共有的东西抽象到一个类里面,该类作为这类对象的基类。在这里我们可以抽象化的便是手机。
实现化
:将接口或抽象类的未实现的方法进行实现。在这里我们可以实现化的就是软件。
将抽象和实现解耦
:有了上面的抽象化和实现化,通过桥接模式来实现解耦。在这里,我们把打开软件 open()
放到软件实现中,而抽象的手机利用模板方法模式定义 openSoftware()
供手机子类去实现,手机子类也是调用软件的 open()
方法,并没有自己实现打开逻辑,也就是解耦了这个打开软件过程。
下面给出案例的代码。
Phone 手机抽象类代码。属性 system
代表系统名称,software
代表要打开的软件,openSoftware()
对外提供打开软件的方法。
abstract class Phone {
private String system;
private Software software;
public abstract void openSoftware();
public String getSystem() {
return system;
}
public void setSystem(String system) {
this.system = system;
}
public Software getSoftware() {
return software;
}
public void setSoftware(Software software) {
this.software = software;
}
}
AndroidPhone 安卓系统手机代码。
class AndroidPhone extends Phone {
public AndroidPhone(Software software){
this.setSystem("Android");
this.setSoftware(software);
}
@Override
public void openSoftware() {
this.getSoftware().open(this);
}
}
IOSPhone IOS 系统手机代码(也就是苹果手机)。
class IOSPhone extends Phone {
public IOSPhone(Software software) {
this.setSystem("IOS");
this.setSoftware(software);
}
@Override
public void openSoftware() {
this.getSoftware().open(this);
}
}
Software 软件接口代码。它有一个方法 open(),用于打开该软件。
interface Software {
void open(Phone phone);
}
Chrome 谷歌浏览器软件代码。
class Chrome implements Software {
@Override
public void open(Phone phone) {
System.out.println("打开 " + phone.getSystem() + " 手机的 Chrome 浏览器");
}
}
FireFox 火狐浏览器软件代码。
class FireFox implements Software {
@Override
public void open(Phone phone) {
System.out.println("打开 " + phone.getSystem() + " 手机的 Firefox 浏览器");
}
}
测试代码如下。
public class BridgeTest {
public static void main(String[] args) {
Software chrome = new Chrome();
Software firefox = new FireFox();
Phone androidPhone = new AndroidPhone(chrome);
androidPhone.openSoftware();
androidPhone.setSoftware(firefox);
androidPhone.openSoftware();
Phone iosPhone = new IOSPhone(chrome);
iosPhone.openSoftware();
iosPhone.setSoftware(firefox);
iosPhone.openSoftware();
}
}
打印结果:
打开 Android 手机的 Chrome 浏览器
打开 Android 手机的 Firefox 浏览器
打开 IOS 手机的 Chrome 浏览器
打开 IOS 手机的 Firefox 浏览器
桥接模式代码已经写完。为什么叫桥接模式呢?因为它将打开软件的具体实现放到了软件实现里面,而不是放在了手机,通过聚合方式去调用软件打开的方法,这就像一条桥一样连接手机和软件。
总结
桥接模式利用了聚合的优点去解决继承的缺点,使得抽象和实现进行分离解耦。正由于解耦,使得有更好的扩展性,加手机类型或者加软件都非常容易,也不会破坏原有的代码。
推荐阅读
公众号后台回复『大礼包』获取 Java、Python、IOS 等教程 加个人微信备注『教程』获取架构师、机器学习等教程

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
前端 api 请求缓存方案
在开发 web 应用程序时,性能都是必不可少的话题。对于webpack打包的单页面应用程序而言,我们可以采用很多方式来对性能进行优化,比方说 tree-shaking、模块懒加载、利用 extrens 网络cdn 加速这些常规的优化。甚至在vue-cli 项目中我们可以使用 --modern 指令生成新旧两份浏览器代码来对程序进行优化。 而事实上,缓存一定是提升web应用程序有效方法之一,尤其是用户受限于网速的情况下。提升系统的响应能力,降低网络的消耗。当然,内容越接近于用户,则缓存的速度就会越快,缓存的有效性则会越高。 以客户端而言,我们有很多缓存数据与资源的方法,例如 标准的浏览器缓存 以及 目前火热的 Service worker。但是,他们更适合静态内容的缓存。例如 html,js,css以及图片等文件。而缓存系统数据,我采用另外的方案。 那我现在就对我应用到项目中的各种 api 请求缓存方案,从简单到复杂依次介绍一下。 方案一 数据缓存 简单的 数据 缓存,第一次请求时候获取数据,之后便使用数据,不再请求后端api。 代码如下: const dataCache = new M...
-
下一篇
Django使用Channels实现WebSocket--下篇
希望通过对这两篇文章的学习,能够对Channels有更加深入的了解,使用起来得心应手游刃有余 通过上一篇《Django使用Channels实现WebSocket--上篇》的学习应该对Channels的各种概念有了清晰的认知,可以顺利的将Channels框架集成到自己的Django项目中实现WebSocket了,本篇文章将以一个Channels+Celery实现web端tailf功能的例子更加深入的介绍Channels 先说下我们要实现的目标:所有登录的用户可以查看tailf日志页面,在页面上能够选择日志文件进行监听,多个页面终端同时监听任何日志都互不影响,页面同时提供终止监听的按钮能够终止前端的输出以及后台对日志文件的读取 最终实现的结果见下图 接着我们来看下具体的实现过程 技术实现 所有代码均基于以下软件版本: python==3.6.3 django==2.2 channels==2.1.7 celery==4.3.0 celery4在windows下支持不完善,所以请在linux下运行测试 日志数据定义 我们只希望用户能够查询固定的几个日志文件,就不是用数据库仅借助setting...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS关闭SELinux安全模块
- 设置Eclipse缩进为4个空格,增强代码规范
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- CentOS8编译安装MySQL8.0.19
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- MySQL数据库在高并发下的优化方案
- SpringBoot2更换Tomcat为Jetty,小型站点的福音