Java设计模式之桥梁(Bridge)模式

桥梁模式的结构

桥梁模式是对象的结构模式。

如上图所示,系统含有两个等级结构:

  • 由抽象化角色和修正抽象化角色组成的抽象化等级结构。
  • 由实现化角色和两个具体实现化角色所组成的实现化等级结构。

桥梁模式所涉及的角色有:

  • 抽象化(Abstraction)角色:抽象化给出的定义,并保存一个对实现化对象的引用。
  • 修正抽象(Refined Abstraction)化角色:扩展抽象化角色,改变和修正父类对抽象化的定义。
  • 实现化(Implementor)角色:这个角色给出实现化角色的接口,但不给出具体的实现。必须指出的是,这个接口不一定和抽象化角色的接口定义相同,实际上,这两个接口可以非常不一样。 实现化角色应当只给出底层操作,而抽象化角色应当只给出基于底层操作的更高一层的操作。
  • 具体实现化(Concrete Implementor)角色:这个角色给出实现化角色接口的具体实现。

对象是对行为的封装,而行为是由方法实现的。在这个示意性系统里,抽象化等级结构中的类封装了operation()方法;而实现化等级结构中的类封装的是operationImp()方法。

抽象化等级结构中的商业方法通过向对应的实现化对象的委派实现自己的功能,这意味着抽象化角色可以通过向不同的实例化对象委派,来达到动态地转换自己的功能的目的。

示意性源码:

抽象化角色,商业方法operation()的实现是通过向实现化对象的委派(调用operationImp()方法)实现的。

abstract public class Abstraction {
	protected Implementor imp;
	/**
	 * 某个商业方法
	 */
	public void operation() {
		imp.operationImp();
	}
}

修正抽象化角色,商业方法被置换掉了。

public class RefinedAbstraction extends Abstraction {
	/**
	 * 某个商业方法在修正抽象化角色的实现
	 */
	public void operation() {
		// improved logic
	}
}

实现化角色抽象类Implementor中声明一个抽象方法operationImp(),这个方法必须由具体子类实现。

abstract public class Implementor {
	/**
	 * 某个商业方法的实现化声明
	 */
	public abstract void operationImp();
}

具体实现化角色实现了抽象类Implementor所声明的商业方法operationImp()。

public class ConcreteImplementorA extends Implementor {
	/**
	 * 某个商业方法的实现化实现
	 */
	public void operationImp() {
		System.out.println("Do something...");
	}
}

一般而言,实现化角色中的每一个方法都应当有一个抽象化角色中的某一个方法与之相对应,但是,反过来则不一定。换言之,抽象化角色的接口比实现化角色的接口宽。抽象化角色除了提供与实现化角色相关的方法之外,还有可能提供其他的商业方法;而实现化角色则往往仅为实现抽象化角色的相关行为而存在。

例子

空中巴士(Airbus)、波音(Boeing)和麦道(McDonnell-Douglas)都是飞机制造商,它们都生产载客飞机(Passenger Plane)和载货飞机(Cargo Plane)。现在需要设计一个系统,描述这些飞机制造商以及它们所制造的飞机种类。

设计方案一

在这个设计方案里,有两个子接口:客机和货机。所有的具体飞机又都要继承自Airbus,Boeing和MD等超类。这样一来,每一个具体飞机都带有两个超类型:飞机制造商类型,客、货机类型。

这样设计造成具体飞机与飞机制造商、飞机种类之间的耦合过强,无法满足“开-闭原则”:

  • 需要向系统引进新的飞机制造商;
  • 需要向系统引进新的飞机类型。

设计方案二

桥梁模式,抽象化角色——飞机的种类,实现化角色——飞机制造商。

客机和货机经过一个飞机的“转世”桥梁,可以分别“投胎”到空中巴士、波音和麦道等飞机制造商哪里,“出生”为不同牌子的飞机。

由于这个“转世”桥梁实际上是一个聚合关系,因此可以动态地变化。所以如果系统需要加入新的飞机种类或者飞机制造商的话,已有的各个角色不必改变,需要改变的仅仅是一个多态性的聚合关系。

示意性源代码:

抽象化角色类Airplane。

abstract public class Airplane {
	protected AirplaneMaker airplaneMaker;
	abstract public void fly();

	protected Airplane(AirplaneMaker airplaneMaker) {
		this.airplaneMaker = airplaneMaker;
	}
}

载客飞机和载货飞机属于修正抽象化角色。

public class PassengerPlane extends Airplane {
	public void fly() {
		// Write your code here
		airplaneMaker.produce();
	}

	public PassengerPlane(AirplaneMaker airplaneMaker) {
		super(airplaneMaker);
	}
}

public class CargoPlane extends Airplane {
	public void fly() {
		// Write your code here
		airplaneMaker.produce();
	}

	public CargoPlane(AirplaneMaker airplaneMaker) {
		super(airplaneMaker);
	}
}

实现化角色是飞机制造商AirplaneMaker,给出修正抽象化角色所需要实现的接口。

abstract public class AirplaneMaker {
	abstract public void produce();
}

具体实现化角色是Airbus、Boeing、MD。

public class Airbus extends AirplaneMaker {
	public void produce() {
		// Write your code here
		System.out.println("produce by Airbus");
	}
}

public class Boeing extends AirplaneMaker {
	public void produce() {
		// Write your code here
		System.out.println("produce by Boeing");
	}
}

public class MD extends AirplaneMaker {
	public void produce() {
		// Write your code here
		System.out.println("produce by MD");
	}
}

客户端代码。

public class BridgePatternDemo {
	public static void main(String[] args) {
		Airplane mdPassengerPlane = new PassengerPlane(new MD());
		Airplane mdCargoPlane = new CargoPlane(new MD());
		mdPassengerPlane.fly();
		mdCargoPlane.fly();

		Airplane boeingPassengerPlane = new PassengerPlane(new Boeing());
		Airplane boeingCargoPlane = new CargoPlane(new Boeing());
		boeingPassengerPlane.fly();
		boeingCargoPlane.fly();
	}
}

现在,如果需要增加新的飞机制造商或者新的飞机种类,只需要向系统引进一个新的修正抽象化角色或者一个新的具体实现化角色即可。即系统的功能可以在不修改已有代码的情况下得到扩展,符合“开-闭”原则。

到此这篇关于Java设计模式之桥梁(Bridge)模式的文章就介绍到这了,更多相关Java 桥梁模式内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java通俗易懂系列设计模式之代理模式

    前言 国内程序员好像普遍对百度都没好感,而且百度近些年产生了不少负面的新闻,像16年的魏则西事件,近期的导演吴京黑白照事件,以及最近作家六六斥百度李彦宏:"你是做搜索引擎还是骗子首领",还有一件就是与程序员有关的:搜索Julia语言,在百度和Google得出首条搜索结果的差异性而被吐槽.Google虽然受欢迎,但是在国内因内容审查问题未解决而不能使用,如果我们要使用它就必须使用代理服务器,由于放置代理服务器的地区区域可以访问google,所以我们可以先访问代理服务器,通过代理服务器转发

  • Java通俗易懂系列设计模式之策略模式

    介绍 策略设计模式是行为设计模式之一.当我们为特定任务使用多个算法时,使用策略模式,客户端决定在运行时使用的实际实现. 策略模式的最佳示例之一是Collections.sort()采用Comparator参数的方法.基于Comparator接口的不同实现,对象将以不同的方式进行排序. 实例 对于我们的示例,我们将尝试实施一个简单的购物车,我们有两种付款策略 - 使用信用卡或使用PayPal. 首先,我们将为我们的策略模式示例创建接口,在我们的例子中,支付金额作为参数传递. 支付方式:Paymen

  • Java设计模式之抽象工厂模式详解

    一.什么是抽象工厂模式 为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类,这称之为抽象工厂模式(Abstract Factory).我们并不关心零件的具体实现,而是只关心接口(API).我们仅使用该接口(API)将零件组装称为产品. 二.示例程序   1.抽象的零件:Item类 package com.as.module.abstractfactory; /** * 抽象的零件 * @author Andy * @date 2021/4/29 23:16 */ public

  • Java设计模式之观察者模式(Observer模式)

    一.观察者模式是什么? 当对象间存在一对多关系时,则使用观察者模式(Observer Pattern).当一个对象被修改时,则会自动通知依赖它的对象.观察者模式属于行为型模式. 人话: 就像微信公众号推送消息,订阅的人能收到,没订阅的收不到,还可以取消/添加订阅 二.模式分析 2.1 四个角色 抽象主题(抽象被观察者角色):也就是一个抽象主题,它把所有对观察者对象的引用保存在一个集合中,每个主题都可以有任意数量的观察者.抽象主题提供一个接口,可以增加和删除观察者角色.一般用一个抽象类和接口来实现

  • Java通俗易懂系列设计模式之责任链模式

    概述 责任链设计模式是行为设计模式之一. 责任链模式用于在软件设计中实现松散耦合,其中来自客户端的请求被传递到对象链以处理它们.然后链中的对象将自己决定谁将处理请求以及是否需要将请求发送到链中的下一个对象. JDK中的责任链模式示例 让我们看一下JDK中责任链模式的例子,然后我们将继续实现这种模式的真实例子.我们知道在try-catch块代码中我们可以有多个catch块.这里每个catch块都是处理该特定异常的处理器. 因此当try块中发生任何异常时,它会发送到第一个catch块进行处理.如果c

  • 一文搞懂Java设计模式之责任链模式

    简述: 前端时间再看一些类库的源码,发现责任链模式的强大之处,尤其是和建造者模式的结合后强大的动态可扩展性更是牛逼的一塌糊涂.接下来赶紧了解一下吧! 我们先来了解一下什么是责任链模式: 职责链模式(Chain of Responsibility):使多个对象都有机会处理同一个请求,从而避免请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. 应用场景: 为完成同一个请求,如果存在多个请求处理器以及未知请求处理器个数或者请求处理器可动态配置的

  • JAVA初探设计模式的六大原则

    前言 我想用贴近生活的语句描述一下自己对六种原则的理解.也就是不做专业性的阐述,而是描述一种自己学习后的理解和感受,因为能力一般而且水平有限,也许举的例子不尽妥当,还请谅解原本我是想用JavaScript编写的,但是JavaScript到现在还没有提出接口的概念,而用TypeScript写又感觉普及度还不算特别高,所以还是决定用Java语言编写 首先要提的是:六大原则的灵魂是面向接口,以及如何合理地运用接口 P1.单一职责原则(Single Responsibility Principle) 应

  • Java设计模式之单例模式简介

    一.饿汉式(静态常量) public class Face { private static final Face instance = new Face(); static Face getInstance() { return instance; } private Face() { } } 优点:这种写法比较简单,就是在类装载的时候就完成实例化.避免了线程同步问题. 缺点:在类装载的时候就完成实例化,没有懒加载的效果.如果从始至终从未使用过这个实例,则会造成内存的浪费. 二.饿汉式(静态代

  • Java设计模式之装饰模式详解

    一.装饰模式引入例子 一个快餐店计算价格问题举例: 快餐店有炒面.炒饭这些快餐,可以额外附加鸡蛋.火腿.培根这些配菜,加配菜需要额外加钱,并且每个配菜的价钱不一样,计算快餐价格如何实现? 1.1 一般设计 1.2 使用继承方式的一般设计存在的问题 横向扩展性不好:如果要再加一种配料(火腿肠),我们就会发现需要给FriedRice和FriedNoodles分别定义一个子类.如果要新增一个快餐品类(炒河粉)的话,就需要定义更多的子,会出现类爆炸的问题. 继承适合于纵向扩展 二.装饰模式 2.1 装饰

  • Java设计模式之原型模式详解

    一.前言 原型模式是一种比较简单的模式,也非常容易理解,实现一个接口,重写一个方法即完成了原型模式.在实际应用中,原型模式很少单独出现.经常与其他模式混用,他的原型类Prototype也常用抽象类来替代. 该模式的思想就是将一个对象作为原型,对其进行复制.克隆,产生一个和原对象类似的新对象.在Java中,复制对象是通过clone()实现的,先创建一个原型类,通过实现Cloneable 接口 public class Prototype implements Cloneable { public

  • Java通俗易懂系列设计模式之装饰模式

    介绍 装饰模式,是面向对象编程领域中,一种动态地往一个类中添加新的行为的设计模式.就功能而言,装饰模式相比生成子类更为灵活,这样可以给某个对象而不是整个类添加一些功能. 意图:动态地给一个对象添加一些额外的职责和增加功能. 主要解决:一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀. 何时使用:在不想增加很多子类的情况下扩展类. 如何解决:将具体功能职责划分,同时继承装饰者模式. 关键代码: 1.Component 类充当抽象角色,不

  • Java设计模式之代理模式详解

    一.代理模式 代理模式就是有一个张三,别人都没有办法找到他,只有他的秘书可以找到他.那其他人想和张三交互,只能通过他的秘书来进行转达交互.这个秘书就是代理者,他代理张三. 再看看另一个例子:卖房子 卖房子的步骤: 1.找买家 2.谈价钱 3.签合同 4.和房产局签订一些乱七八糟转让协议 一般卖家只在签合同的时候可能出面一下,其他的1,2,4都由中介去做.那你问这样有什么用呢? 首先,一个中介可以代理多个卖房子的卖家,其次,我们可以在不修改卖家的代码的情况下,给他实现房子加价.打广告等等夹带私货的

  • Java通俗易懂系列设计模式之建造者模式

    介绍 今天我们将研究java中的Builder模式.Builder 设计模式是一种创造性的设计模式,如工厂模式和抽象工厂模式. 当Object包含许多属性时,引入了Builder模式来解决Factory和Abstract Factory设计模式的一些问题. 当Object包含许多属性时,Factory和Abstract Factory设计模式存在三个主要问题. 从客户端程序传递到Factory类的参数太多,可能容易出错,因为大多数情况下,参数的类型是相同的,而从客户端来说,很难维护参数的顺序.

随机推荐