Bridge定义:将抽象和行为划分开来,各自独立,但能动态的结合。

为什么使用桥模式

通常,当一个抽象类或接口有多个具体实现(concrete subclass),这些concrete之间关系可能有以下两种:

  • 这多个具体实现之间恰好是并列的,如前面举例,打桩,有两个concrete class:方形桩和圆形桩;这两个形状上的桩是并列的,没有概念上的重复,那么我们只要使用继承就可以了。
  • 实际应用上,常常有可能在这多个concrete class之间有概念上重叠。那么需要我们把抽象共同部分和行为共同部分各自独立开来,原来是准备放在一个接口里,现在需要设计两个接口,分别放置抽象和行为。

例如,一杯咖啡为例,有中杯和大杯之分,同时还有加奶 不加奶之分。如果用单纯的继承,这四个具体实现(中杯 大杯 加奶 不加奶)之间有概念重叠,因为有中杯加奶,也有中杯不加奶,如果再在中杯这一层再实现两个继承,很显然混乱,扩展性极差。那我们使用Bridge模式来实现它。

如何实现桥模式

以上面提到的咖啡 为例。我们原来打算只设计一个接口(抽象类),使用Bridge模式后,我们需要将抽象和行为分开,加奶和不加奶属于行为,我们将它们抽象成一个专门的行为接口。

先看看抽象部分的接口代码:

public abstract class Coffee{
 CoffeeImp coffeeImp;
 public void setCoffeeImp() {
  this.CoffeeImp = CoffeeImpSingleton.getTheCoffeImp();
 }
 public CoffeeImp getCoffeeImp() {return this.CoffeeImp;}
 public abstract void pourCoffee();
}

其中CoffeeImp 是加不加奶的行为接口,看其代码如下:

public abstract class CoffeeImp{
 public abstract void pourCoffeeImp();
}

现在我们有了两个抽象类,下面我们分别对其进行继承,实现concrete class:

//中杯
public class MediumCoffee extends Coffee{
 public MediumCoffee() {setCoffeeImp();}
 public void pourCoffee(){
  CoffeeImp coffeeImp = this.getCoffeeImp();
  //我们以重复次数来说明是冲中杯还是大杯 ,重复2次是中杯
  for (int i = 0; i < 2; i++){
   coffeeImp.pourCoffeeImp();
  }
 }
}
//大杯

public class SuperSizeCoffee extends Coffee{
 public SuperSizeCoffee() {setCoffeeImp();}
 public void pourCoffee(){
  CoffeeImp coffeeImp = this.getCoffeeImp();
  //我们以重复次数来说明是冲中杯还是大杯 ,重复5次是大杯
  for (int i = 0; i < 5; i++){
   coffeeImp.pourCoffeeImp();
  }
 }
}

上面分别是中杯和大杯的具体实现.下面再对行为CoffeeImp进行继承:

//加奶
public class MilkCoffeeImp extends CoffeeImp{
 MilkCoffeeImp() {}
 public void pourCoffeeImp(){
  System.out.println("加了美味的牛奶");
 }
} //不加奶
public class FragrantCoffeeImp extends CoffeeImp{
 FragrantCoffeeImp() {}
 public void pourCoffeeImp(){
  System.out.println("什么也没加,清香");
 }
}

Bridge模式的基本框架我们已经搭好了,别忘记定义中还有一句:动态结合,我们现在可以喝到至少四种咖啡:

  1. 中杯加奶
  2. 中杯不加奶
  3. 大杯加奶
  4. 大杯不加奶

看看是如何动态结合的,在使用之前,我们做个准备工作,设计一个单态类(Singleton)用来hold当前的CoffeeImp:

public class CoffeeImpSingleton{
 private static CoffeeImp coffeeImp;
 public CoffeeImpSingleton(CoffeeImp coffeeImpIn)
 {this.coffeeImp = coffeeImpIn;}
 public static CoffeeImp getTheCoffeeImp(){
  return coffeeImp;
 }
}
看看中杯加奶 和大杯加奶 是怎么出来的: //拿出牛奶
CoffeeImpSingleton coffeeImpSingleton = new CoffeeImpSingleton(new MilkCoffeeImp()); //中杯加奶
MediumCoffee mediumCoffee = new MediumCoffee();
mediumCoffee.pourCoffee(); //大杯加奶
SuperSizeCoffee superSizeCoffee = new SuperSizeCoffee();
superSizeCoffee.pourCoffee();

注意:Bridge模式的执行类如CoffeeImp和Coffee是一对一的关系,正确创建CoffeeImp是该模式的关键。

Bridge模式在EJB中的应用

EJB中有一个Data Access Object (DAO)模式,这是将商业逻辑和具体数据资源分开的,因为不同的数据库有不同的数据库操作。将操作不同数据库的行为独立抽象成一个行为接口DAO,如下:

    • Business Object (类似Coffee)
      实现一些抽象的商业操作:如寻找一个用户下所有的订单。涉及数据库操作都使用DAOImplementor。
    • Data Access Object (类似CoffeeImp)
      一些抽象的对数据库资源操作。
    • DAOImplementor 如OrderDAOCS, OrderDAOOracle, OrderDAOSybase(类似MilkCoffeeImp FragrantCoffeeImp)
      具体的数据库操作,如"INSERT INTO "等语句,OrderDAOOracle是Oracle OrderDAOSybase是Sybase数据库。
    • 数据库 (Cloudscape, Oracle, or Sybase database via JDBC API)

系列文章:

Java设计模式(1)工厂模式(Factory模式)

Java设计模式(2)单态模式(Singleton模式)

Java设计模式(3)建造者模式(Builder模式)

Java设计模式(4)原型模式(Prototype模式)

Java设计模式(5)共享模式/享元模式(Flyweight模式)

Java设计模式(6)桥模式(Bridge模式)

Java设计模式(7)装饰模式(Decorator模式)

Java设计模式(8)组合模式(Composite模式)

Java设计模式(9)适配器模式(Adapter模式)

Java设计模式(10)代理模式(Proxy模式)

Java设计模式(11)外观模式(Facade模式)

Java设计模式(12)迭代模式(Iterator模式)

Java设计模式(13)模板模式(Template模式)

Java设计模式(14)责任链模式(Chain of Responsibility模式)

Java设计模式(15)备忘录模式(Memento模式)

Java设计模式(16)中介模式(Mediator模式)

Java设计模式(17)解释器模式(Interpreter模式)

Java设计模式(18)策略模式(Strategy模式)

Java设计模式(19)状态模式(State模式)

Java设计模式(20)观察者模式(Observer模式)

Java设计模式(21)访问模式(Visitor者模式)

Java设计模式(22)命令模式(Command模式)

Java设计模式(6)桥模式(Bridge模式)的更多相关文章

  1. Java设计模式(22)命令模式(Command模式)

    Command模式是最让我疑惑的一个模式,我在阅读了很多代码后,才感觉隐约掌握其大概原理,我认为理解设计模式最主要是掌握起原理构造,这样才对自己实际编程有指导作用.Command模式实际上不是个很具体 ...

  2. Java设计模式(21)访问模式(Visitor者模式)

    Visitor定义:作用于某个对象群中各个对象的操作.它可以使你在不改变这些对象本身的情况下,定义作用于这些对象的新操作. 在Java中,Visitor模式实际上是分离了collection结构中的元 ...

  3. Java设计模式(19)状态模式(State模式)

    State的定义:不同的状态,不同的行为:或者说,每个状态有着相应的行为. 何时使用状态模式 State模式在实际使用中比较多,适合"状态的切换".因为我们经常会使用If else ...

  4. Java设计模式(18)策略模式(Strategy模式)

    Strategy是属于设计模式中 对象行为型模式,主要是定义一系列的算法,把这些算法一个个封装成单独的类. Stratrgy应用比较广泛,比如,公司经营业务变化图,可能有两种实现方式,一个是线条曲线, ...

  5. Java设计模式(17)解释器模式(Interpreter模式)

    Interpreter定义:定义语言的文法,并且建立一个解释器来解释该语言中的句子. Interpreter似乎使用面不是很广,它描述了一个语言解释器是如何构成的,在实际应用中,我们可能很少去构造一个 ...

  6. Java设计模式(16)中介模式(Mediator模式)

    Mediator定义:用一个中介对象来封装一系列关于对象交互行为. 为何使用Mediator模式/中介模式 各个对象之间的交互操作非常多,每个对象的行为操作都依赖彼此对方,修改一个对象的行为,同时会涉 ...

  7. Java设计模式(15)备忘录模式(Memento模式)

    Memento定义:memento是一个保存另外一个对象内部状态拷贝的对象,这样以后就可以将该对象恢复到原先保存的状态. Memento模式相对也比较好理解,我们看下列代码: public class ...

  8. Java设计模式(13)模板模式(Template模式)

    Template模式定义:定义一个操作中算法的骨架,将一些步骤的执行延迟到其子类中. 其实Java的抽象类本来就是Template模式,因此使用很普遍.而且很容易理解和使用,我们直接以示例开始: pu ...

  9. Java设计模式(12)迭代模式(Iterator模式)

    上了这么多年学,我发现一个问题,好象老师都很喜欢点名,甚至点名都成了某些老师的嗜好,一日不点名,就饭吃不香,觉睡不好似的,我就觉得很奇怪,你的课要是讲的好,同学又怎么会不来听课呢,殊不知:“误人子弟, ...

  10. Java设计模式(11)外观模式(Facade模式)

    外观模式(Facade)的定义:为子系统中的一组接口提供一个一致的界面. Facade一个典型应用就是数据库JDBC的应用,如下例对数据库的操作: public class DBCompare { C ...

随机推荐

  1. Spring Security教程(一):初识Spring Security

    一.概要 Spring Security,这是一种基于 Spring AOP 和 Servlet 过滤器的安全框架.它提供全面的安全性解决方案,同时在 Web 请求级和方法调用级处理身份确认和授权.以 ...

  2. c++中浮点数精度设置

    1.包含头文件<iomanip>,附注manip是manipulator,操控的简写. 2.第一种写法: cout<<setiosflags(ios::); 第二种写法: co ...

  3. ISO-OSI的七层协议经典架构

    OSI(Open System interconnection)开放系统互连参考模型 ISO(International Standards Organization)国际标准化组织 第一层:物理层 ...

  4. Push UIViewController with different orientation to previous

    转自:http://stackoverflow.com/questions/6695837/push-uiviewcontroller-with-different-orientation-to-pr ...

  5. FFmpeg(2)-avformat_open_input()函数详解并示例打开mp4文件

    一. 解封装 pts 是显示的时间 dts是解码的时间, 这个时间是用来做同步. av_register_all(), 注册所有的格式.包括解封装格式和加封装格式. avformat_network_ ...

  6. transfer learning

    https://github.com/jindongwang/transferlearning ftp://ftp.cs.wisc.edu/machine-learning/shavlik-group ...

  7. 构造函数 (C++)

    构造函数是一种可初始化其类的实例的成员函数. 构造函数具有与类相同的名称,没有返回值. 构造函数可以具有任意数量的参数,类可以具有任意数量的重载构造函数. 构造函数可以具有任何可访问性(公共.受保护或 ...

  8. RestTemplate 发送 get 请求使用误区 多值为null

    http://blog.csdn.net/zhousenshan/article/details/71055687 ****************************************** ...

  9. [Java]随记--HttpClient发送put请求

    http://blog.csdn.net/u010989191/article/details/52852155 ******************************************* ...

  10. Python3.5 执行发邮件脚本失败【惑】==>【搞定】

    Python发邮件的代码如下: 只需要填写好加粗字体,即可正常使用. from exchangelib import DELEGATE, Account, Credentials, Message, ...