GOF23设计模式之桥接模式(bridge)
一、桥接模式概述
桥接模式核心要点:
处理多层继承结构,处理多维度变化的场景,将各个维度设计成独立的继承结构,使各个维度可以独立的扩展在抽象层建立关联。
二、桥接模式场景提出与存在问题
商城系统中常见的商品分类,以电脑为类,如何良好的处理商品分类销售的问题?
这个场景中有两个变化的维度:品牌、电脑类型。

(1)不使用桥接模式时:
/**
* 不适用桥接模式时的电脑产品按照类型和品牌分类
* @author CL
*
*/
public interface Computer {
void sale();
} /**
* 类型:台式机
* @author CL
*
*/
class Desktop implements Computer { @Override
public void sale() {
System.out.println("销售台式机");
} } /**
* 类型:笔记本
* @author CL
*
*/
class Laptop implements Computer { @Override
public void sale() {
System.out.println("销售笔记本");
} } /**
* 类型:平板
* @author CL
*
*/
class Pad implements Computer { @Override
public void sale() {
System.out.println("销售平板电脑");
} } /**
* 品牌:联想台式机
* @author CL
*
*/
class LenovoDesktop extends Desktop {
@Override
public void sale() {
System.out.println("销售联想台式机");
}
} /**
* 品牌:联想笔记本
* @author CL
*
*/
class LenovoLaptop extends Desktop {
@Override
public void sale() {
System.out.println("销售联想笔记本");
}
} /**
* 品牌:联想平板电脑
* @author CL
*
*/
class LenovoPad extends Desktop {
@Override
public void sale() {
System.out.println("销售联想平板电脑");
}
} /**
* 品牌:戴尔台式机
* @author CL
*
*/
class DellDesktop extends Desktop {
@Override
public void sale() {
System.out.println("销售戴尔台式机");
}
} /**
* 品牌:戴尔笔记本
* @author CL
*
*/
class DellLaptop extends Desktop {
@Override
public void sale() {
System.out.println("销售戴尔笔记本");
}
} /**
* 品牌:戴尔平板电脑
* @author CL
*
*/
class DellPad extends Desktop {
@Override
public void sale() {
System.out.println("销售戴尔平板电脑");
}
} /**
* 品牌:华硕台式机
* @author CL
*
*/
class ASUSDesktop extends Desktop {
@Override
public void sale() {
System.out.println("销售华硕台式机");
}
} /**
* 品牌:华硕笔记本
* @author CL
*
*/
class ASUSLaptop extends Desktop {
@Override
public void sale() {
System.out.println("销售华硕笔记本");
}
} /**
* 品牌:华硕平板电脑
* @author CL
*
*/
class ASUSPad extends Desktop {
@Override
public void sale() {
System.out.println("销售华硕平板电脑");
}
}
测试:
/**
* 客户端
* @author CL
*
*/
public class Client { public static void main(String[] args) {
Computer c1 = new LenovoDesktop();
c1.sale();
} }
控制台输出:
销售联想台式机
(2)存在问题
① 扩展性问题(类的个数膨胀问题)
如果要增加一个新的电脑类型,如智能手机,则要增加各个品牌下面的类;
如果要增加一个新的品牌,也要增加各种电脑类型的类。
② 违反了单一职责原则
一个类有两个职责:品牌+电脑类型。每个类都有两个原因引起变化。
三、桥接模式应用
(1)电脑类型维度
/**
* 维度:电脑类型
* @author CL
*
*/
public class Computer {
protected Brand brand; public Computer(Brand brand) {
this.brand = brand;
} public void sale() {
brand.sale();
}
} /**
* 台式机
* @author CL
*
*/
class Desktop extends Computer { public Desktop(Brand brand) {
super(brand);
} @Override
public void sale() {
super.sale();
System.out.println("销售台式机");
}
} /**
* 笔记本
* @author CL
*
*/
class Laptop extends Computer { public Laptop(Brand brand) {
super(brand);
} @Override
public void sale() {
super.sale();
System.out.println("销售笔记本");
}
} /**
* 平板电脑
* @author CL
*
*/
class Pad extends Computer { public Pad(Brand brand) {
super(brand);
} @Override
public void sale() {
super.sale();
System.out.println("销售平板电脑");
}
}
(2)品牌维度
/**
* 一种维度:品牌
* @author CL
*
*/
public interface Brand {
void sale();
} /**
* 联想电脑
* @author CL
*
*/
class Lenovo implements Brand { @Override
public void sale() {
System.out.println("销售联想电脑");
} } /**
* 戴尔电脑
* @author CL
*
*/
class Dell implements Brand { @Override
public void sale() {
System.out.println("销售戴尔电脑");
} } /**
* 华硕电脑
* @author CL
*
*/
class ASUS implements Brand { @Override
public void sale() {
System.out.println("销售华硕电脑");
} }
(3)测试
/**
* 客户端
* @author CL
*
*/
public class Client { public static void main(String[] args) {
//销售联想笔记本电脑
Computer c1 = new Laptop(new Lenovo());
c1.sale(); //销售戴尔台式机
Computer c2 = new Desktop(new Dell());
c2.sale();
} }
控制台输出:
销售联想电脑
销售笔记本
销售戴尔电脑
销售台式机
(4)假如现在要在品牌维度上增加一种品牌:宏碁电脑,只需要在品牌维度中增加如下代码:
/**
* 宏碁电脑
* @author CL
*
*/
class Acer implements Brand { @Override
public void sale() {
System.out.println("销售宏碁电脑");
} }
(5)测试
/**
* 客户端
* @author CL
*
*/
public class Client { public static void main(String[] args) {
//销售联想笔记本电脑
Computer c1 = new Laptop(new Lenovo());
c1.sale(); //销售戴尔台式机
Computer c2 = new Desktop(new Dell());
c2.sale(); //销售宏碁的平板电脑
Computer c3 = new Pad(new Acer());
c3.sale();
} }
控制台输出:
销售联想电脑
销售笔记本
销售戴尔电脑
销售台式机
销售宏碁电脑
销售平板电脑
四、桥接模式总结
(1)桥接模式可以取代多层继承的方案。
多层继承违背了单一职责原则,复用性较差,类的个数也非常多。桥接模式可以极大的减少子类的个数,从而降低管理和维护的成本。
(2)桥接模式极大的提高了系统的可扩展性。
在两个变化的维度中任意扩展一个维度。都不需要修改原有的代码,符合开闭原则。
五、桥接模式实际开发中的应用场景
(1)JDBC驱动程序;
(2)AWT中的Peer框架;
(3)人力资源系统中的奖金计算模块:
奖金分类:个人奖金、团队奖金、激励奖金
部门分类:开发部门、运维部门、人事部门
(4)OA系统中的消息处理:
业务类型:普通消息、加密消息、紧急消息
发送方式:系统内部、手机短信、邮件、飞秋
(5)…………
GOF23设计模式之桥接模式(bridge)的更多相关文章
- 乐在其中设计模式(C#) - 桥接模式(Bridge Pattern)
原文:乐在其中设计模式(C#) - 桥接模式(Bridge Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 桥接模式(Bridge Pattern) 作者:webabcd 介绍 ...
- 【设计模式】桥接模式 Bridge Pattern
开篇还是引用吕振宇老师的那篇经典的文章<设计模式随笔-蜡笔与毛笔的故事>.这个真是太经典了,没有比这个例子能更好的阐明桥接模式了,这里我就直接盗来用了. 现在市面上卖的蜡笔很多,各种型号, ...
- python 设计模式之桥接模式 Bridge Pattern
#写在前面 前面写了那么设计模式了,有没有觉得有些模式之间很类似,甚至感觉作用重叠了,模式并不是完全隔离和独立的,有的模式内部其实用到了其他模式的技术,但是又有自己的创新点,如果一味地认为每个模式都是 ...
- 二十四种设计模式:桥接模式(Bridge Pattern)
桥接模式(Bridge Pattern) 介绍将抽象部分与它的实现部分分离,使它们都可以独立地变化. 示例有一个Message实体类,对它的操作有Insert()和Get()方法,现在使这些操作的抽象 ...
- 【GOF23设计模式】桥接模式
来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_桥接模式.多层继承结构.银行日志管理.管理系统消息管理.人力资源的奖金计算 未用桥接模式: package com.te ...
- [设计模式] 7 桥接模式 bridge
#include<iostream> using namespace std; class AbstractionImp { public: virtual ~AbstractionImp ...
- 设计模式之桥接模式(Bridge)--结构模型
1.意图 将抽象部分与它的实现部分分离,使它们可以独立地变化. 2.适用性 你不希望在抽象和它的实现部分之间有一个固定的绑定关系. 类的抽象与它的实现都应该可以通过子类的方式加以扩展. 抽象部分与实现 ...
- 设计模式 笔记 桥接模式 Bridge
//---------------------------15/04/15---------------------------- //Bridge 桥接模式----对象结构型模式 /* 1:意图:将 ...
- 设计模式之桥接模式(Bridge)
桥接模式与原理:将抽象部分与实现部分分离,使它们都可以独立的变化.最终的结果表现在实现类中.两者之间属于等价关系,即实现部分和抽象部分可以相互交换. 代码如下 #include <iostrea ...
随机推荐
- bzoj3600
题解: 好像是什么替罪羊树 然后看了几个题解 然后就抄了一边 代码: #include<bits/stdc++.h> using namespace std; ; int n,m,rt,R ...
- Elasticsearch 在分布式系统中深度分页问题
理解为什么深度分页是有问题的,我们可以假设在一个有 5 个主分片的索引中搜索. 当我们请求结果的第一页(结果从 1 到 10 ),每一个分片产生前 10 的结果,并且返回给 协调节点 ,协调节点对 5 ...
- Kconfig介绍
https://www.kernel.org/doc/Documentation/kbuild/kconfig-language.txt
- 课堂/会议同屏教学解决方案之RTSP/RTP over UDP组播解决方案
问题 在之前的博客<EasyIPCamera实现Windows PC桌面.安卓Android桌面同屏直播,助力无纸化会议系统>我们描述了一套基于EasyIPCamera的同屏功能,但是这个 ...
- wampserver搭建本地服务器
打开..\wamp\bin\apache\apache2.4.9\conf\httpd.conf配置文件, <Directory "c:/wamp/www/"> # # ...
- python pass关键字神奇吗
参考文献:http://blog.sina.com.cn/s/blog_76e94d210100vz3e.html 1.空语句 do nothing2.保证格式完整3.保证语义完整 好吧!它什么也没干 ...
- [interview]螺旋队列问题
摘要 本文主要讲解三种螺旋队列的实现方式和打印输出: 从中心往外端顺时针旋转,记为『外螺旋队列』 从左顶点开始,绕剩下的最大圈顺时针往内旋转,记为『内螺旋队列』 从左顶点开始,之字形旋转(只能同行同列 ...
- Ubuntu网络代理问题
问题描述 新开机的电脑,不开lantern就上不了网.很气. 解决过程 首先当然是寻求解决方案了.未果 然后就是妥协,每次先开一次lantern.(其实也不是很麻烦是吧,哎,是的是的) 今天早晨友人来 ...
- vue运行原理
Vue工作原理小结 本文能帮你做什么? 1.了解vue的双向数据绑定原理以及核心代码模块 2.缓解好奇心的同时了解如何实现双向绑定 为了便于说明原理与实现,本文相关代码主要摘自vue源码, 并进行了简 ...
- manacher 算法 这个人确实写得太好了;
O(n)回文子串(Manacher)算法 资料来源网络 参见:http://www.felix021.com/blog/read.php?2040 问题描述: 输入一个字符串,求出其中最大的回文子串. ...