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 ...
随机推荐
- Java进阶5 面向对象的陷阱
Java进阶5 面向对象的陷阱 20131103 Java是一门纯粹面向对象的编程语言,Java面向对象是基础,而且面向对象的基本语法非常多,非常的细,需要程序员经过长时间的学习才可以掌握.本章重点介 ...
- 【zznu-夏季队内积分赛3-G】2333
题目描述 “别人总说我瓜,其实我一点也不瓜,大多数时候我都机智的一批“ 宝儿姐考察你一道很简单的题目.给你一个数字串,你能判断有多少个连续子串能整除3吗? 输入 多实例输入,以EOF结尾,每行一个数字 ...
- 用U盘安装ubuntu
用U盘安装操作系统,并不鲜见,对于Windows,可以用大白菜安装XP.Win7等,本质上是在U盘上安装一个小型的windows(WinPE),然后利用ghost一键还原技术,把U盘中的XP.gho( ...
- C++(笔记)浅析vector容器的实例
http://www.runoob.com/w3cnote/cpp-vector-container-analysis.html 转载请注明出处 浅然的专栏 https://blog.csdn.net ...
- Composer 扩展包安装方法
问题说明 我们经常要往现有的项目中添加扩展包,有时候因为文档的错误引导,如下图来自 这个文档 的: composer update 这个命令在我们现在的逻辑中,可能会对项目造成巨大伤害. 因为 com ...
- echarts-detail---散点图
data4 = [{ xAxis: result.AvgEvaluate, seriesId: ', name: '基干360综合分' }, { yAxis: evalue, seriesId: ', ...
- Shell 命令行实现将一个站点页面全部下载到本地并替换其中链接的脚本
Shell 命令行实现将一个站点页面全部下载到本地并替换其中链接的脚本 不知道为什么,我总想用 Shell 脚本来实现把一个站点内容给下载下来.但是下载什么站点我确不知道.今天尝试了一下利用 curl ...
- python学习之多线程(二)
使用multiprocessing 使用multiprocessing.dummy 单使用multiprocessing模块的指的是多进程,使用multiprocessing.dummy则表示使用的是 ...
- html(对php也有效)页面自动刷新和跳转(简单版本)
<html> <head><title>html页面自动刷新和跳转</title><meta http-equiv="Refres ...
- 实现同时提交多个form(基础方法) 收集(转)
方法一: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4 ...