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 ...
随机推荐
- xcode自动打ipa包脚本 资料
http://webfrogs.me/2012/09/19/buildipa/ http://blog.csdn.net/baxiaxx/article/details/8267295 http:// ...
- 【Android UI】如何做一个纯粹的Android app UI 设计
原文:http://android.eoe.cn/topic/summary 许多开发者会在多个平台上发布应用.如果您打算为 Android 开发应用,请记住在不同的平台需要遵守不同的要求和惯例.在某 ...
- ssl与tls的差别
1)版本号:TLS记录格式与SSL记录格式相同,但版本号的值不同,TLS的版本1.0便 用的版 本号为SSLv3.1. 2) 报文鉴别码:SSLv3.0和TLS的MAC算法的范围不同,但两者的安全层度 ...
- rpm_快速安装saltstake
安装EPEL源:(mast和minion都需要安装) [root@c02 src]# wget http://mirrors.sohu.com/fedora-epel/6/x86_64/epel-re ...
- lua -- 点击关闭窗口中的子界面
function UIBagController:initBoxView( ) self.panelBox = tolua.cast(UIHelper:seekWidgetByName(self.ow ...
- 为什么我们做分布式要使用Redis
绝大部分写业务的程序员,在实际开发中使用 Redis 的时候,只会 Set Value 和 Get Value 两个操作,对 Redis 整体缺乏一个认知.这里对 Redis 常见问题做一个总结,解决 ...
- 关于 Nginx upstream keepalive 的说明
模块是 HttpUpstreamModule,配置的一个例子: [shell]upstream http_backend { server 127.0.0.1:8080; keepalive 1 ...
- UI设计文本框解决Placeholder的在IE10 以下 IE 9 IE8 IE 7 的兼容问题
创建JS文件 placeholderfriend.js (function($) { /** * 牛叉的解决方案 */ var placeholderfriend = { focus: functio ...
- python--使用MySQL数据库
1.安装mysqlsudo apt-get install mysql-server Sudo apt-get install mysql-client 2.安装MySQL-python驱动sudo ...
- VirtualBox与VMWare网络冲突
VirtualBox安装一个XP后,发现老是上不到网,怎么折腾都不行, 后来发现设备管理器中 vmware accelerated amd pcnet adapter #2显示黄色感叹号 不对呀,这是 ...