模式的定义
将抽象部分与实现部分分离,使它们都可以独立的变化。
模式的使用场景
如果一个系统需要在构件的抽象化角色和具体化角色之间添加更多的灵活性,避免在两个层次之间建立静态的联系。设计要求实现化角色的任何改变不应当影响客户端,或者实现化角色的改变对客户端是完全透明的。需要跨越多个平台的图形和窗口系统上。一个类存在两个独立变化的维度,且两个维度都需要进行扩展。
UML类图
角色介绍
抽象化(Abstraction)角色:抽象化给出的定义,并保存一个对实现化对象的引用。 修正抽象化(Refined Abstraction)角色:扩展抽象化角色,改变和修正父类对抽象化的定义。实现化(Implementor)角色:这个角色给出实现化角色的接口,但不给出具体的实现。必须指出的是,这个接 口不一定和抽象化角色的接口定义相同,实际上,这两个接口可以非常不一样。实现化角色应当只给出底层操作,而抽象化角色应当只给出基于底层操作的更高一层的操作。具体实现化(ConcreteImplementor)角色:这个角色给出实现化角色接口的具体实现。
模式的简单实现
- 介绍
其实Java的虚拟机就是一个很好的例子,在不同平台平台上,用不同的虚拟机进行实现,这样只需把Java程序编译成符合虚拟机规范的文件,且只用编译一次,便在不同平台上都能工作。 但是这样说比较抽象,用一个简单的例子来实现bridge模式。
编写一个程序,使用两个绘图的程序的其中一个来绘制矩形或者原型,同时,在实例化矩形的时候,它要知道使用绘图程序1(DP1)还是绘图程序2(DP2)。
(ps:假设dp1和dp2的绘制方式不一样,它们是用不同方式进行绘制,示例代码,不讨论过多细节)
- 实现源码
首先是两个绘图程序dp1,dp2
//具体的绘图程序类dp1
public class DP1 {
public void draw_1_Rantanle(){
System.out.println("使用DP1的程序画矩形");
}
public void draw_1_Circle(){
System.out.println("使用DP1的程序画圆形");
}
}
//具体的绘图程序类dp2
public class DP2 {
public void drawRantanle(){
System.out.println("使用DP2的程序画矩形");
}
public void drawCircle(){
System.out.println("使用DP2的程序画圆形");
}
}
接着抽象的形状Shape和两个派生类:矩形Rantanle和圆形Circle
//抽象化角色Abstraction
abstract class Shape {
//持有实现的角色Implementor(作图类)
protected Drawing myDrawing;
public Shape(Drawing drawing) {
this.myDrawing = drawing;
}
abstract public void draw();
//保护方法drawRectangle
protected void drawRectangle(){
//this.impl.implmentation()
myDrawing.drawRantangle();
}
//保护方法drawCircle
protected void drawCircle(){
//this.impl.implmentation()
myDrawing.drawCircle();
}
}
//修正抽象化角色Refined Abstraction(矩形)
public class Rantangle extends Shape{
public Rantangle(Drawing drawing) {
super(drawing);
}
@Override
public void draw() {
drawRectangle();
}
}
//修正抽象化角色Refined Abstraction(圆形)
public class Circle extends Shape {
public Circle(Drawing drawing) {
super(drawing);
}
@Override
public void draw() {
drawCircle();
}
}
最后,我们的实现绘图的Drawing和分别实现dp1的V1Drawing和dp2的V2Drawing
//实现化角色Implementor
//implmentation两个方法,画圆和画矩形
public interface Drawing {
public void drawRantangle();
public void drawCircle();
}
//具体实现化逻辑ConcreteImplementor
//实现了接口方法,使用DP1进行绘图
public class V1Drawing implements Drawing{
DP1 dp1;
public V1Drawing() {
dp1 = new DP1();
}
@Override
public void drawRantangle() {
dp1.draw_1_Rantanle();
}
@Override
public void drawCircle() {
dp1.draw_1_Circle();
}
}
//具体实现化逻辑ConcreteImplementor
//实现了接口方法,使用DP2进行绘图
public class V2Drawing implements Drawing{
DP2 dp2;
public V2Drawing() {
dp2 = new DP2();
}
@Override
public void drawRantangle() {
dp2.drawRantanle();
}
@Override
public void drawCircle() {
dp2.drawCircle();
}
}
在这个示例中,图形Shape类有两种类型,圆形和矩形,为了使用不同的绘图程序绘制图形,把实现的部分进行了分离,构成了Drawing类层次结构,包括V1Drawing和V2Drawing。在具体实现类中,V1Drawing控制着DP1程序进行绘图,V2Drawing控制着DP2程序进行绘图,以及保护的方法drawRantangle,drawCircle(Shape类中) 。