跟着实例学习设计模式(9)-桥接模式bridge(结构型)

桥接模式属于结构型设计模式。

设计意图:将抽象部分与实现部分分离,使它们都可以独立的变化。

一看到设计意图,大家可能有些发懵,我们看到的继承和接口不都是抽象和实现分离的吗?尤其是接口和抽象类都是这样的实现啊!那怎么还有这么个桥接的分离呢?

我们先来看个例子。

例如:汽车品牌内置导航仪,我们希望实现,每个品牌的导航仪都可以在任何一个牌子的汽车上安装并启动。

汽车品牌有两个:宝马、奔驰。

导航仪有三个牌子:神行者、北斗、高德。

来看正常的设计,我们肯定是会这样的采用继承来实现每个组合的安装和启动处理的,每个品牌+导航都需要一个独立的类来实现功能,但是这里有个一个问题,如果我们再增加一个品牌那么就意味着要再增加三个类,每增加一个品牌都是如此,这是一件太痛苦的事啊!所以能找到一种方式不用增加类就可以实现新品牌安装并开启导航仪的功能吗?

来看下面的图,我们将汽车品牌和导航仪品牌做一个组合。

如果能这样组合,那每增加一个汽车品牌时,就只需要增加一个品牌类就好,这个品牌和之前的导航仪组合就可以了。

我们可以看出导航仪和汽车其实是一种聚合关系,也就是导航仪只是汽车的一部分,而这一部分不随着汽车消亡而消失。所以他们之间是松耦合关系,聚合关系。

桥接模式是遵循了合成/聚合复用原则(稍后我们在介绍该原则),我们来看通用通用类图。

Abstraction:定义抽象类的接口,该接口中定义如何使用Implementor接口类型对象的方法。

RefinedAbstraction:实现由Abstraction定义的接口方法,可能会有自己的一些私有方法。

Implementor:定义Abstraction抽象的实现,这种实现是一种嫁接的关系,就像计算机主板和声卡、显卡的关系一样,它可以是一个接口, Implementor接口提供Abstraction抽象接口需要的操作,而 Abstraction则定义了基于这些基本操作的较高层次的操作。

ConcreteImplementor:实现Implementor接口并定义它的具体实现。

让我们来看实例代码,通过实例代码可以更好的理解桥接模式的神奇,它真的是实现可插拔式的模式。

package com.bridge;

/**
 * 1:汽车品牌抽象类,这个抽象类主要是导航的安装与启动,其它的配件也可以在该类提供方法,
 * 但是为了开-闭原则,最好可以在另加其它接口。
 * 2:桥接就是要实现插拔方式的调用,我们想一下主板和插件,主板提供接口定义该接口的功能,
 * 由插件来实现该接口的功能。这就是桥接的主要思想,抽象与实现分离。
 * 3:该类定义了如何注入一个接口的方法install,并定义了如何操作注入接口的具体实现的方法open。
 * 4:这里其实可以使用接口,如果使用接口,那就更灵活,以后我再给大家写一个多个接口的例子
 * ,每个配件一个接口。这样每个品牌的汽车可以实现多个接口也就可以增加不同的配件了。
 * @author gaoxu
 * 实践出真知!
 */
public abstract class AbstractVehicleBrand {
	/**安装导航方法
	 * @author gaoxu
	 * @param n
	 */
	public abstract void install(INavigator n);

	/**开启导航
	 * 开启导航是调用导航接口实现类的方法,其实那个方法就是我们这个方法的延伸。
	 * @author gaoxu
	 */
	public abstract void open();
}</span>
<span style="font-size:14px;">package com.bridge;

/**
 * @author gaoxu
 * 实践出真知!
 */
public class BMWVehicle extends AbstractVehicleBrand{
	//导航
	INavigator navigator = null;

	@Override
	public void install(INavigator n) {

		navigator = n;
	}

	@Override
	public void open() {
		navigator.work();
	}

}
package com.bridge;

/**
 * @author gaoxu
 * 实践出真知!
 */
public class BenzVehicle extends AbstractVehicleBrand{
	//导航
	INavigator navigator = null;
	@Override
	public void install(INavigator n) {
		navigator = n;
	}

	@Override
	public void open() {
		navigator.work();
	}

}

导航插件的公共接口,定义了导航的行为方法。

package com.bridge;

/**
 * @author gaoxu
 * 实践出真知!
 */
public interface INavigator {
	public void work();
}
package com.bridge;

public class SXZNavigator implements INavigator{

	@Override
	public void work() {
		System.out.println("我是神行者导航!");
	}

}
package com.bridge;

public class BDNavigator implements INavigator{

	@Override
	public void work() {
		System.out.println("我是北斗导航!");
	}
}

我们来看客户端代码

package com.bridge;

public class Client {
	public static void main(String[] para){
		//我们现在是实现不同品牌的汽车,可以安装不同牌子的导航,也就是把汽车和导航聚合了起来。
		//我们是通过桥接的方式完成了这种聚合,桥接方式比继承的方式要更灵活,它是汽车与配件可
                  以独立各自的发展。
		//我们可以实现的聚合关系:宝马+北斗,宝马+神行者,奔驰+北斗,奔驰+身形者
		//当然我们还可以给汽车配置更多不同的后装配件例如:空气净化器等。
		INavigator bdNavigator = new BDNavigator();
		INavigator sxzNavigator = new SXZNavigator();
		//宝马安装北斗导航
		AbstractVehicleBrand bmw = new BMWVehicle();
		bmw.install(bdNavigator);
		bmw.open();
		//奔驰安装了神行者导航
		AbstractVehicleBrand benz = new BMWVehicle();
		benz.install(sxzNavigator);
		benz.open();
	}
}

优点:把两种都具有变化的分类实现独立变化,真的是松耦合的典范。

使用范围:多个具有变化的分类共同实现功能时易采用桥接模式。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-09 22:09:27

跟着实例学习设计模式(9)-桥接模式bridge(结构型)的相关文章

设计模式07: Bridge 桥接模式(结构型模式)

Bridge 桥接模式(结构型模式) 抽象与实现 抽象不应该依赖于实现细节,实现细节应该依赖于抽象. 抽象B稳定,实现细节b变化 问题在于如果抽象B由于固有的原因,本身并不稳定,也有可能变化,怎么办? 举例来说 假如我们需要开发一个同时支持PC和手机的坦克游戏,游戏在PC和手机上功能都一样,都有同样的类型,面临同样的需求变化,比如坦克可能有多种不同的型号:T50,T75,T90…… 对于其中坦克设计,我们可能很容易设计出来一个Tank的抽象基类: /// <summary> /// 抽象Tan

如何让孩子爱上设计模式 ——10.桥接模式(Bridge Pattern)

如何让孩子爱上设计模式 --10.桥接模式(Bridge Pattern) 我有故事,你有酒吗?这年头写个技术文不讲个故事都不行,行,我讲: 还有发现很多的技术博文都开始有喜欢往文中插入几个表情的趋势了, 但是你真的插的姿势对了吗?这种事情不是随便插的,来来来,给你 见识下如何在适当的场景插入适当的表情以让读者感觉到易可赛艇, 本文以讲故事插表情为主,讲述桥接模式为辅,多图预警, 简书上排版可能有些问题,最佳排版可见: https://www.zybuluo.com/coder-pig/note

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

开篇还是引用吕振宇老师的那篇经典的文章<设计模式随笔-蜡笔与毛笔的故事>.这个真是太经典了,没有比这个例子能更好的阐明桥接模式了,这里我就直接盗来用了. 现在市面上卖的蜡笔很多,各种型号,各种颜色种类繁多, 假如一盒蜡笔有24种颜色,那么它能涂抹出24种不同的颜色来,蜡笔型号是固定的,如果想画出各种线条那么就要购买不同型号的蜡笔,假如我们要涂抹出粗,中,细三种线条,那么我们就要买3盒粗,中,细型号的蜡笔才能满足需求,那么就是3盒*24色=72只蜡笔.假如使用毛笔来作画,我们需要准备3只粗,中,

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

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

设计模式-11 外观模式(结构型模式)

一  外观模式 外观模式(Facade Pattern)隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口.这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性. 主要解决:降低访问复杂系统的内部子系统时的复杂度,简化客户端与之的接口. 关键代码:在客户端和复杂系统之间再加一层,这一次将调用顺序.依赖关系等处理好. 使用场景: JAVA 的三层开发模式 1.为复杂的模块或子系统提供外界访问的模块. 2.子系统相对独立. 3.预防低水平人员带来的风险. 类图

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

1.意图 将抽象部分与它的实现部分分离,使它们可以独立地变化. 2.适用性 你不希望在抽象和它的实现部分之间有一个固定的绑定关系. 类的抽象与它的实现都应该可以通过子类的方式加以扩展. 抽象部分与实现部分可以独立变化,而不会相互影响. 从多维度扩展应用程序. 3.结构 4.参与者 Abstraction: 定义抽象的接口:维护一个指向Implementor对象的引用. RefinedAbstraction: 扩充有Abstracttion定义的接口. Implementor: 定义实现类的接口,

设计模式-08桥接模式(Bridge Pattern)

1.模式动机 设想如果要绘制矩形.圆形.椭圆.正方形,我们至少需要4个形状类,但是如果绘制的图形需要具有不同的颜色,如红色.绿色.蓝色等,此时至少有如下两种设计方案: 第一种设计方案是为每一种形状都提供一套各种颜色的版本. 第二种设计方案是根据实际需要对形状和颜色进行组合 对于有两个变化维度(即两个变化的原因)的系统,采用方案二来进行设计系统中类的个数更少,且系统扩展更为方便.设计方案二即是桥接模式的应用.桥接模式将继承关系转换为关联关系,从而降低了类与类之间的耦合,减少了代码编写量. 当然,这

23种设计模式-----创建型模式、结构型模式

一.创建型模式(都是用来帮助创建对象的) 1.单例模式 作用:保证一个类只有一个实例,并且提供一个访问该实例的全局访问点 应用:Windows的任务管理器.回收站:项目中读取配置文件的类:网站的计数器:应用程序的日志应用:数据库连接池:操作系统的文件系统:Application:Spring中的bean:Servlet:spring MVC框架/struts1框架中的控制器对象 选用:占用资源小.不需要延时加载--------枚举-->饿汉           占用资源大 .需要延时    --

【设计模式】—— 桥接模式Bridge

前言:[模式总览]——————————by xingoo 模式意图 这个模式使用的并不多,但是思想确实很普遍.就是要分离抽象部分与实现部分. 实现弱关联,即在运行时才产生依赖关系. 降低代码之间的耦合. 模式结构 Abstraction 抽象部分的基类,定义抽象部分的基础内容. RefinedAbstraction 抽象部分的扩充,用于对基类的内容补充,添加特定场景的业务操作. Implementor 实现部分的基类,定义实现部分的基本内容. ConcreteImplementor 具体的实现类

设计模式之桥接模式 Bridge

代码实现 public interface Brand { void sale(); } class Lenovo implements Brand{ @Override public void sale() { System.out.println("销售联想电脑"); } } class Dell implements Brand{ @Override public void sale() { System.out.println("销售戴尔电脑"); } }