前言

这次介绍结构型设计模式中的第二种模式,桥接模式。 使用桥接模式的目的就是为了解耦,松散的耦合更利于扩展,但是会增加相应的代码量和设计难度。

桥接模式

桥接模式是为了将抽象化与实现化解耦,让二者可以独立地变化。方便对每一部分的扩展,以及单独的维护。抽象化的一方与实现化的一方之间建立一个桥梁,这样两者的依赖关系就可以通过这个桥梁来建立了。

举例

三个小动物要过河,分别是小猪,小鸡,小马,小猪要去河对面的空地晒太阳,小鸡要去河对面的小树林里找虫子吃,小马要去河对面的草地里吃草。那么它们三个都要经过小桥才能过河。有了场景下面来说一下代码的实现,先创建一个小桥的接口。

/**
* 小桥
*/
public interface Bridge { /**
* 目的地
*/
void targetLand();
}

因为三个小动物的目的地不一样,所以每一个目的地对应一个实现。

小猪的目的地

/**
* 空地
*/
public class VacantLand implements Bridge{ /**
* 目的地
*/
@Override
public void targetLand() {
System.out.println("空旷的地方,晒太阳");
}
}

小鸡的目的地

/**
* 小树林
*/
public class Forest implements Bridge{ /**
* 目的地
*/
@Override
public void targetLand() {
System.out.println("小树林,觅食。");
}
}

小马的目的地

/**
* 草地
*/
public class Grassland implements Bridge{
/**
* 目的地
*/
@Override
public void targetLand() {
System.out.println("大草原,尽情奔腾。");
}
}

下面来实现抽象化的部分,每个小动物都要过桥去往不同的目的地,所以它们都要相同的过桥行为。所以定义一个动物抽象类。

/**
* 小动物
*/
public abstract class Animal { /**
* 桥
*/
Bridge bridge; /**
* 过桥
*/
abstract void willToDo();
}

小猪

/**
* 小猪
*/
public class Piglet extends Animal {
/**
* 过桥
*/
@Override
public void willToDo() {
System.out.println("我是小猪要过桥去 ");
}
}

小鸡

/**
* 小鸡
*/
public class Chick extends Animal {
/**
* 过河桥
*/
@Override
public void willToDo() {
System.out.println("我是小鸡要过桥去 ");
}
}

小马

/**
* 小马
*/
public class Pony extends Animal {
/**
* 过桥
*/
@Override
public void willToDo() {
System.out.println("我是小马要过桥去 ");
}
}

测试例子

public class TestBridge {

    public static void main(String[] args) {

        Animal animal = new Chick();

        animal.bridge = new Forest();
animal.willToDo();
animal.bridge.targetLand();
}
}

运行结果

我是小鸡要过桥去
小树林,觅食。

这就是一个完整的桥接模式的例子,这样使得小动物和要去的目的地解耦了。如果再来了一个小动物,例如小鸭子,它只需要继承Animal类即可,如果它的目的地已经存在了就直接使用现有的目的地类,如果要去的目的地不存在(例如小鸭子要去池塘),那么可以再创建一个池塘的目的地,然后实现自Bridge就可以了。

结构

下面来介绍一下桥接模式的结构,如下图所示。

从上面的结构图中我们可以看出来,桥接模式其实是分为四个角色的。

抽象化角色(Animal类):定义抽象化,并保存一个对实现化对象的引用。

抽象化扩展角色(Chick、Piglet、Pony等具体的小动物类):实现和扩展抽象化角色的功能。

实现化角色(Bridge接口):此角色给出了实现化角色的接口,定义了实现化角色的行为。

具体实现化角色(VacantLand、GrassLand、Forest等目的地类):实现化角色接口的具体实现类。

桥接模式的优缺点

优点

1、分离抽象和实现部分:

分离了抽象和实现部分,提高了系统的灵活性,这样有助于对系统进行分层,从而产生更好的结构化的系统。

2、更好的扩展性:

因为抽象部分和实现部分分离开了,所以这两部分可以独立扩展,互不影响,大大提高了系统的可扩展性。

3、可动态切换:

由于分离了抽象和实现,那么在实现桥接的时候,可以实现动态的选择和使用具体的实现,也就是在运行期间动态切换实现。

4、减少了子类的数量:

从抽象和实现两个维度来看,如果不是用桥接模式的话,这两个维度的子类,在发生变化时影响到的数量是两个维度子类的乘积。而使用了桥接模式后影响到的数量是两个维度的子类的和。

缺点

增加了系统的理解和设计难度,入手并不是那么容易了,因为聚合关系定义在抽象层,所以需要开发者对抽象进行设计和编程。

想了解更多的设计模式请查看Java设计模式学习记录-GoF设计模式概述

Java设计模式学习记录-桥接模式的更多相关文章

  1. Java设计模式学习记录-模板方法模式

    前言 模板方法模式,定义一个操作中算法的骨架,而将一些步骤延迟到子类中.使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤. 模板方法模式 概念介绍 模板方法模式,其实是很好理解的,具体 ...

  2. Java设计模式学习记录-状态模式

    前言 状态模式是一种行为模式,用于解决系统中复杂的对象状态转换以及各个状态下的封装等问题.状态模式是将一个对象的状态从该对象中分离出来,封装到专门的状态类中,使得对象的状态可以灵活多变.这样在客户端使 ...

  3. Java设计模式学习记录-备忘录模式

    前言 这次要介绍的是备忘录模式,也是行为模式的一种 .现在人们的智能手机上都会有备忘录这样一个功能,大家也都会用,就是为了记住某件事情,防止以后自己忘记了.那么备忘录模式又是什么样子的呢?是不是和手机 ...

  4. Java设计模式学习记录-迭代器模式

    前言 这次要介绍的是迭代器模式,也是一种行为模式.我现在觉得写博客有点应付了,前阵子一天一篇,感觉这样其实有点没理解透彻就写下来了,而且写完后自己也没有多看几遍,上次在面试的时候被问到java中的I/ ...

  5. Java设计模式学习记录-解释器模式

    前言 这次介绍另一个行为模式,解释器模式,都说解释器模式用的少,其实只是我们在日常的开发中用的少,但是一些开源框架中还是能见到它的影子,例如:spring的spEL表达式在解析时就用到了解释器模式,以 ...

  6. Java设计模式学习记录-命令模式

    前言 这次要介绍的是命令模式,这也是一种行为型模式.最近反正没有面试机会我就写博客呗,该投的简历都投了.然后就继续看书,其实看书也会给自己带来成就感,原来以前不明白的东西,书上已经给彻底的介绍清楚了, ...

  7. Java设计模式学习记录-外观模式

    前言 这次要介绍的是外观模式(也称为门面模式),外观模式也属于结构型模式,其实外观模式还是非常好理解的,简单的来讲就是将多个复杂的业务封装成一个方法,在调用此方法时可以不必关系具体执行了哪些业务,而只 ...

  8. Java设计模式学习记录-代理模式

    代理模式 代理模式是常见设计模式的一种,代理模式的定义是:为其他对象提供一种代理以控制对这个对象的访问. 在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起 ...

  9. Java设计模式学习记录-建造者模式

    前言 今天周末,有小雨,正好也不用出门了,那就在家学习吧,经过了两周的面试,拿到了几个offer,但是都不是自己很想去的那种,要么就是几个人的初创小公司,要么就是开发企业内部系统的这种传统开发,感觉这 ...

随机推荐

  1. [SoapUI] 从测试套件,测试用例,测试步骤,测试数据各个级别控制是否执行

    自动保存 # -*- coding: utf-8 -*- import java.awt.Color import org.apache.poi.ss.usermodel.Cell import or ...

  2. numpy版本查看以及升降

     如题,参考:https://zhuanlan.zhihu.com/p/29026597 pip show numpy 查看numpy版本; pip install -U numpy==1.12.0, ...

  3. mac开发常用工具和插件记录

    1.alfred 是 Mac 系统上一款专注于效率提升的著名应用,它能帮你快速打开网页.快速进行自定义搜索.查看剪贴板历史.快速查询单词等等.Alfred 提供的功能虽然很多,但目的只有一个 —— 那 ...

  4. hdu 1325 && poj 1308 Is It A Tree?(并查集)

    Description A tree is a well-known data structure that is either empty (null, void, nothing) or is a ...

  5. 异常与Final

    Throwable 类是 Java 语言中所有错误或异常的超类(这就是一切皆可抛的东西).它有两个子类:Error和Exception.Error:用于指示合理的应用程序不应该试图捕获的严重问题.这种 ...

  6. CSS---伪类选择器

    伪类选择器的作用: 控制标签在不同状态下的样式. 标签的四种状态: link:没有访问过的状态: hover:鼠标经过的状态: active:鼠标激活(按下但没有松开)的状态: visited:已经被 ...

  7. Android开发 - 更"聪明"的申请权限方式

    在Android6.0以后,很多权限需要动态申请,只有在用户点同意后,我们才能使用对应API,因此,正确申请权限就显得很重要. 常用方式 通常我们使用这种方式来判断权限状态: private stat ...

  8. Ideas

    1.蔬菜店,自带种植的菜地.(实现蔬菜都是新采摘的.) 这个试用于农村,因为需要土地.农村现在蔬菜店大多也是外出进货.有些菜放久了,就坏掉了. 这里有问题就是,(1).如果销量不够,怎么让蔬菜不烂在菜 ...

  9. C语言中几个常用数学计算函数ceil(), floor(), round()的用法

    最近在实现算法的过程中,遇到了使用几个数学计算函数,感觉挺有意思,就记下来 方便以后使用. ceil(x)返回不小于x的最小整数值(然后转换为double型). floor(x)返回不大于x的最大整数 ...

  10. python chr()和ord()的含义和使用方法

    通过help 查看相关函数的帮助文档 >>>help (chr) chr(...) chr(i) -> character Return a string of one cha ...