一、桥接模式概述

  桥接模式核心要点:

    处理多层继承结构,处理多维度变化的场景,将各个维度设计成独立的继承结构,使各个维度可以独立的扩展在抽象层建立关联。

二、桥接模式场景提出与存在问题

  商城系统中常见的商品分类,以电脑为类,如何良好的处理商品分类销售的问题?

  这个场景中有两个变化的维度:品牌、电脑类型。

    

  (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)的更多相关文章

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

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

  2. 【设计模式】桥接模式 Bridge Pattern

    开篇还是引用吕振宇老师的那篇经典的文章<设计模式随笔-蜡笔与毛笔的故事>.这个真是太经典了,没有比这个例子能更好的阐明桥接模式了,这里我就直接盗来用了. 现在市面上卖的蜡笔很多,各种型号, ...

  3. python 设计模式之桥接模式 Bridge Pattern

    #写在前面 前面写了那么设计模式了,有没有觉得有些模式之间很类似,甚至感觉作用重叠了,模式并不是完全隔离和独立的,有的模式内部其实用到了其他模式的技术,但是又有自己的创新点,如果一味地认为每个模式都是 ...

  4. 二十四种设计模式:桥接模式(Bridge Pattern)

    桥接模式(Bridge Pattern) 介绍将抽象部分与它的实现部分分离,使它们都可以独立地变化. 示例有一个Message实体类,对它的操作有Insert()和Get()方法,现在使这些操作的抽象 ...

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

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

  6. [设计模式] 7 桥接模式 bridge

    #include<iostream> using namespace std; class AbstractionImp { public: virtual ~AbstractionImp ...

  7. 设计模式之桥接模式(Bridge)--结构模型

    1.意图 将抽象部分与它的实现部分分离,使它们可以独立地变化. 2.适用性 你不希望在抽象和它的实现部分之间有一个固定的绑定关系. 类的抽象与它的实现都应该可以通过子类的方式加以扩展. 抽象部分与实现 ...

  8. 设计模式 笔记 桥接模式 Bridge

    //---------------------------15/04/15---------------------------- //Bridge 桥接模式----对象结构型模式 /* 1:意图:将 ...

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

    桥接模式与原理:将抽象部分与实现部分分离,使它们都可以独立的变化.最终的结果表现在实现类中.两者之间属于等价关系,即实现部分和抽象部分可以相互交换. 代码如下 #include <iostrea ...

随机推荐

  1. html中引入另一个html文件

    https://segmentfault.com/q/1010000002954318

  2. poj3656

    题解: 二分图最大匹配 根据三角形不等式 直接上最大匹配即可 注意编圈取相反数 代码: #include<iostream> #include<algorithm> #incl ...

  3. wget 认知及常用命令【转载】

    https://www.cnblogs.com/lxz88/p/6278268.html https://www.cnblogs.com/cindy-cindy/p/6847502.html

  4. LeetCode OJ:Implement Trie (Prefix Tree)(实现一个字典树(前缀树))

    Implement a trie with insert, search, and startsWith methods. 实现字典树,前面好像有道题做过类似的东西,代码如下: class TrieN ...

  5. 职责链模式(Chain of Responsibility)

    一.责任链模式介绍 责任链模式:将能够处理同一类请求的对象连成一条链,使这些对象都有机会处理请求,所提交的请求沿着链传递.从而避免请求的 发送者和接受者之间的耦合关系.链上的对象逐个判断是否有能力处理 ...

  6. 使用VisualStudio读写NI FPGA板卡实例(基于FPGA Interface C API Generator)

    实验平台说明:安装了NI LabVIEW 2015 32bit版本,安装了NI FPGA Interface C API Generator,安装了硬件PCIe-7842R:安装了Visual Stu ...

  7. 怎么样在python 3.6里安装tensorflow?

    首先要下载python3.6: https://www.python.org/downloads/release/python-361/ 接着下载: numpy-1.13.0-cp36-none-wi ...

  8. 【Java实战】源码解析为什么覆盖equals方法时总要覆盖hashCode方法

    1.背景知识 本文代码基于jdk1.8分析,<Java编程思想>中有如下描述: 另外再看下Object.java对hashCode()方法的说明: /** * Returns a hash ...

  9. Android深入理解JNI(一)JNI原理与静态、动态注册

    前言 JNI不仅仅在NDK开发中应用,它更是Android系统中Java与Native交互的桥梁,不理解JNI的话,你就只能停留在Java Framework层.这一个系列我们来一起深入学习JNI. ...

  10. Jmeter用表格查看结果

    Sample#:编号类似id Start Time:开始时间 Thread Name:线程名称 Label:请求名称 Sample Time:取样时间ms Status:状态 Bytes:接受字节数 ...