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

 更新时间:2021年05月10日 09:59:13   作者:通信侠  
这篇文章主要介绍了Java设计模式之桥梁(Bridge)模式,文中有非常详细的代码示例,对正在学习Java设计模式的小伙伴们有很好的帮助,需要的朋友可以参考下

桥梁模式的结构

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

桥梁模式的示意性系统的结构图

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

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

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

  • 抽象化(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 桥梁模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MyBatis-Plus的apply用法小结

    MyBatis-Plus的apply用法小结

    apply方法是一个非常有用的功能,apply方法允许用户直接在QueryWrapper或LambdaQueryWrapper中添加原生SQL片段,本文就详细的介绍一下apply方法,感兴趣的可以了解一下
    2024-10-10
  • Java 从Set里面取出有序的记录详解及实例

    Java 从Set里面取出有序的记录详解及实例

    这篇文章主要介绍了Java 从Set里面取出有序的记录详解及实例的相关资料,需要的朋友可以参考下
    2017-06-06
  • java并发编程中实现可见性的四种可行方案解析

    java并发编程中实现可见性的四种可行方案解析

    这篇文章主要介绍了java并发编程中实现可见性的四种可行方案解析,使用关键字volatile和使用锁(如synchronized关键字或者java.util.concurrent包中的锁)来确保对共享变量的修改在多线程环境中能够正确地被其他线程所观察到,需要的朋友可以参考下
    2023-08-08
  • 详解SpringBoot构建Docker镜像的3种方式

    详解SpringBoot构建Docker镜像的3种方式

    这篇文章主要介绍了SpringBoot构建Docker镜像的3种方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06
  • Spring Boot使用Servlet及Filter过程详解

    Spring Boot使用Servlet及Filter过程详解

    这篇文章主要介绍了Spring Boot使用Servlet及Filter过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07
  • Java 代理(Proxy)的原理及应用

    Java 代理(Proxy)的原理及应用

    动态代理技术就是用来产生一个对象的代理对象的。 我们在开发中之所以要产生一个对象的代理对象,主要用于拦截对真实业务对象的访问。本文主要介绍了Java 代理的使用,感兴趣的可以了解一下
    2021-05-05
  • SpringBoot请求处理之常用参数注解介绍与源码分析

    SpringBoot请求处理之常用参数注解介绍与源码分析

    SpringBoot是一种整合Spring技术栈的方式(或者说是框架),同时也是简化Spring的一种快速开发的脚手架,本篇让我们一起学习请求处理、常用注解和方法参数的小技巧
    2022-10-10
  • Java中logback 自动刷新不生效的问题解决

    Java中logback 自动刷新不生效的问题解决

    本文主要介绍了Java中logback 自动刷新不生效的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-05-05
  • Java微信公众平台开发(8) 多媒体消息回复

    Java微信公众平台开发(8) 多媒体消息回复

    这篇文章主要为大家详细介绍了Java微信公众平台开发第八步,微信多媒体消息回复,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-04-04
  • Java利用自定义注解、反射实现简单BaseDao实例

    Java利用自定义注解、反射实现简单BaseDao实例

    下面小编就为大家带来一篇Java利用自定义注解、反射实现简单BaseDao实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08

最新评论