Java设计模式(6)桥模式(Bridge模式)
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模式的基本框架我们已经搭好了,别忘记定义中还有一句:动态结合,我们现在可以喝到至少四种咖啡:
- 中杯加奶
- 中杯不加奶
- 大杯加奶
- 大杯不加奶
看看是如何动态结合的,在使用之前,我们做个准备工作,设计一个单态类(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设计模式(5)共享模式/享元模式(Flyweight模式)
Java设计模式(14)责任链模式(Chain of Responsibility模式)
Java设计模式(17)解释器模式(Interpreter模式)
Java设计模式(6)桥模式(Bridge模式)的更多相关文章
- Java设计模式(22)命令模式(Command模式)
Command模式是最让我疑惑的一个模式,我在阅读了很多代码后,才感觉隐约掌握其大概原理,我认为理解设计模式最主要是掌握起原理构造,这样才对自己实际编程有指导作用.Command模式实际上不是个很具体 ...
- Java设计模式(21)访问模式(Visitor者模式)
Visitor定义:作用于某个对象群中各个对象的操作.它可以使你在不改变这些对象本身的情况下,定义作用于这些对象的新操作. 在Java中,Visitor模式实际上是分离了collection结构中的元 ...
- Java设计模式(19)状态模式(State模式)
State的定义:不同的状态,不同的行为:或者说,每个状态有着相应的行为. 何时使用状态模式 State模式在实际使用中比较多,适合"状态的切换".因为我们经常会使用If else ...
- Java设计模式(18)策略模式(Strategy模式)
Strategy是属于设计模式中 对象行为型模式,主要是定义一系列的算法,把这些算法一个个封装成单独的类. Stratrgy应用比较广泛,比如,公司经营业务变化图,可能有两种实现方式,一个是线条曲线, ...
- Java设计模式(17)解释器模式(Interpreter模式)
Interpreter定义:定义语言的文法,并且建立一个解释器来解释该语言中的句子. Interpreter似乎使用面不是很广,它描述了一个语言解释器是如何构成的,在实际应用中,我们可能很少去构造一个 ...
- Java设计模式(16)中介模式(Mediator模式)
Mediator定义:用一个中介对象来封装一系列关于对象交互行为. 为何使用Mediator模式/中介模式 各个对象之间的交互操作非常多,每个对象的行为操作都依赖彼此对方,修改一个对象的行为,同时会涉 ...
- Java设计模式(15)备忘录模式(Memento模式)
Memento定义:memento是一个保存另外一个对象内部状态拷贝的对象,这样以后就可以将该对象恢复到原先保存的状态. Memento模式相对也比较好理解,我们看下列代码: public class ...
- Java设计模式(13)模板模式(Template模式)
Template模式定义:定义一个操作中算法的骨架,将一些步骤的执行延迟到其子类中. 其实Java的抽象类本来就是Template模式,因此使用很普遍.而且很容易理解和使用,我们直接以示例开始: pu ...
- Java设计模式(12)迭代模式(Iterator模式)
上了这么多年学,我发现一个问题,好象老师都很喜欢点名,甚至点名都成了某些老师的嗜好,一日不点名,就饭吃不香,觉睡不好似的,我就觉得很奇怪,你的课要是讲的好,同学又怎么会不来听课呢,殊不知:“误人子弟, ...
- Java设计模式(11)外观模式(Facade模式)
外观模式(Facade)的定义:为子系统中的一组接口提供一个一致的界面. Facade一个典型应用就是数据库JDBC的应用,如下例对数据库的操作: public class DBCompare { C ...
随机推荐
- Spring Security教程(一):初识Spring Security
一.概要 Spring Security,这是一种基于 Spring AOP 和 Servlet 过滤器的安全框架.它提供全面的安全性解决方案,同时在 Web 请求级和方法调用级处理身份确认和授权.以 ...
- c++中浮点数精度设置
1.包含头文件<iomanip>,附注manip是manipulator,操控的简写. 2.第一种写法: cout<<setiosflags(ios::); 第二种写法: co ...
- ISO-OSI的七层协议经典架构
OSI(Open System interconnection)开放系统互连参考模型 ISO(International Standards Organization)国际标准化组织 第一层:物理层 ...
- Push UIViewController with different orientation to previous
转自:http://stackoverflow.com/questions/6695837/push-uiviewcontroller-with-different-orientation-to-pr ...
- FFmpeg(2)-avformat_open_input()函数详解并示例打开mp4文件
一. 解封装 pts 是显示的时间 dts是解码的时间, 这个时间是用来做同步. av_register_all(), 注册所有的格式.包括解封装格式和加封装格式. avformat_network_ ...
- transfer learning
https://github.com/jindongwang/transferlearning ftp://ftp.cs.wisc.edu/machine-learning/shavlik-group ...
- 构造函数 (C++)
构造函数是一种可初始化其类的实例的成员函数. 构造函数具有与类相同的名称,没有返回值. 构造函数可以具有任意数量的参数,类可以具有任意数量的重载构造函数. 构造函数可以具有任何可访问性(公共.受保护或 ...
- RestTemplate 发送 get 请求使用误区 多值为null
http://blog.csdn.net/zhousenshan/article/details/71055687 ****************************************** ...
- [Java]随记--HttpClient发送put请求
http://blog.csdn.net/u010989191/article/details/52852155 ******************************************* ...
- Python3.5 执行发邮件脚本失败【惑】==>【搞定】
Python发邮件的代码如下: 只需要填写好加粗字体,即可正常使用. from exchangelib import DELEGATE, Account, Credentials, Message, ...