一:桥梁模式的用意
将抽象化与实现化脱耦,使得二者可以独立地变化,使得二者可以独立地变化,这就是桥梁模式的用意:
(A)抽象化:存在于多个实体中的共同的概念性联系,就是抽象化,作为一个过程,抽象化就是忽略一些信息,从而把不现的实体当作同样的实体来对待.
(B)实现化:把抽象的东西用把它具体的描述出来,就是实现化.
(C)脱耦:所谓耦合,就是两个实体的行为的某种强关联,而将它们的强关联去掉就叫脱耦。在这里,脱耦是指将抽象化和实现化之间的耦合解脱开,或者说是将它们之间的强关联改成弱关联(所谓强关联,就是在编译的时期已经确定的,无法在运行时期动态改变的关联,所谓弱关联,就是可以动态地确定并且可以在运行时期动态地改变的关联,显然,在Java语言中,继承关系是强关联,而聚合关系是弱关联。将两个角色之间的继承关系改为聚合关系,就是将它们之间的强关联换成了弱关联,因此,桥梁模式中的所谓脱耦,就是指在一个软件系统的抽象化和实现化之间使用聚合关系而不是继承关系,从而使两者可以相对独立地变化,这就是桥梁模式的用意.)
二:桥梁模式中的角色
(A)抽象化角色(Abstraction)角色:抽象化给出的定义,并保存一个对实现化对象的引用
(B)修正抽象化(Refined Abstraction)角色:扩展抽象化角色,改变和修正父类对抽象的定义
(C)实现化角色(Implementor)角色:这个角色给出实现化角色的接口,但不给出具体的实现,必须指出的是,这个接口不一定和抽象化角色的接口定义相同,实际是,这两个接口可以非常不一样。实现化角色应当只给出底层操作,而抽象化角色应当只给出基于底层操作的更高一层的操作
(D)具体实现(Concrete Implementor)角色:这个角色给出实现化角色接口的具体实现
抽象经等级结构中的商业方法通过向对应的实现化对象的委派实现自己的功能,这意味抽象化角色可以通过向不同的实现化对象委派来达到动态地转换自己的功能的目的.
下面给出示意性的代码:
package cai.milenfan.basic.test;
public abstract class Abstraction {
protected Implementor imp;
//一个商业方法
public void operation(){
imp.operationImp();
}
}
package cai.milenfan.basic.test;
public class RefinedAbstraction extends Abstraction{
//某个商业方法在修正抽象角色的实现
public void operation(){
//improved logic
}
}
package cai.milenfan.basic.test;
public abstract class Implementor {
public abstract void operationImp();
}
package cai.milenfan.basic.test;
public class ConcreteImplementor extends Implementor{
public void operationImp() {
System.out.println("do something......");
}
}
三:Java语言中的Peer架构
一个Java的软件系统总是带有所在的操作系统的视感(Look and Feel)。如果一个软件系统是在Unix系统上面开发的,那么开发人员看到的是Motif用户界面的视感,在Windows上面使用这个系统的客户看到的是Windows用户界面的视感,而一个在Macintosh上面使用的用户看到的则是Macintosh用户界面的视感...Java是怎么做到这一点的?
(A)AWT的Peer架构
Java语言是通过所谓的Peer架构做到这一点的.
在一个java应用程序和真正的显示屏之间还有几个软件架构层次,假设现在考察的是一个Scrollbar构件,那么在显示屏上看到的是一个本地的滚动条,与所在的操作系统的任何其他滚动条没有区别,因为这个与系统有关的滚动条实际上是Java的Scrollbar对象的Peer对象所产生的,这个对象的类型是java.awt.peer.ScrollbarPeer,而不是Java应用程序所使用的类型为java.awt.Scrollbar的对象,这个Peer对象会首先截获诸如鼠标单击这样的事件,然后将有关信息传递给Java的Scrollbar对象。
一般地,在每一个Java构件和它的Peer构件之间都有一个Peer接口,这个Peer接口定义出每一个Java构件与其peer构件之间的关系,它使得一个像Scrollbar这样的构件可以动态地与任何操作系统的本地滚动条发生Peer关系,Button和ButtonPeer的通信如下,Button是一个Java构件,通过Toolkit对象与本地的Peer构件通信:
Java中的Button-----addNotify()---->Toolkit-----createButton()----->Native Button
一般而言,Java程序员只需要知道Java所提供的构件,而不需要知道系统底层所使用的peer构件.
(B)Peer接口
Java为Awt中的每一个Gui构件都提供了一个Peer构件,这个peer构件是所属的Java构件在本地环境中的实现化,比如Choice是一个AWT提供的GUI构件,它允许用户在一个列中选择一个或者多个项,一个Java应用程序的开发人员只需要考虑Choice对象所提供的接口就可以了,用户运行这个系统时,这个Choice对象被动态地与一个合适的底层Peer对象联系起来,这个Peer对象会按照指令执行正确的操作,这个将Java的GUI构件与本地环境的Peer构件联系起来的接口就是所谓的peer接口,AWT提供的所有peer接口都放在java.awt.peer库中.
(C)java.awt.peer库
ComponentPeer接口是所有的(非菜单)视窗构件的Peer接品的超级接口
MenuCoomponentPeer给出了所有菜单视窗构件的超类型
FontPeer是Font构件的超类型
创建一个视窗构件并不会间即创建一个对应的Peer对象,只有当视窗的addNotify()方法被调用时,所对应的Peer构件才会被创建出来.
(D)桥梁模式在Java中的应用
在awt库中的每一个Component的子类都有一个ComponentPeer的子类与之匹配,所有Component的子类都属于一个等级结构,而所有的ComponentPeer的子类都属于另一个等级结构,Component类型和ComponentPeer类型通过Toolkit对象相互通信.抽象类Component是各种个体的视窗构件的超类型,这些视窗构件是与操作系统的细节无关,它们向外界提供统一的功能接口,ComponentPeer是各种Peer对象的超类型,这些peer对象负责处理与操作系统细节密切相关的功能的实现,具体视窗构件对象通过向相应的Peer对象进行功能委派,达到利用ComponentPeer的功能的目的.
Component相当于桥梁模式中的抽象角色,Button等相当于修正抽象角色,ComponentPeer相当于实现化角色,而ButtonPeer相当于个体实现化角色,系统根据当前操作系统动态地选择Button对象所使用底层实现。
(E)JDBC驱动器中的桥梁模式