Posted on 2010-07-29 13:56
林光炎 閱讀(644)
評論(0) 編輯 收藏 所屬分類:
JAVA
1、核心意圖:
將抽象部分和實現部分分離,使它們都可以獨立的變化。
該模式的目標是通過把高層的抽象和底層的實現分開,分別構建自己的類層次結構,并通過實現部分的接口將兩部分進行橋接,從而達到高層抽象和底層實現可以獨立的方便擴展的目的。其核心是分離,和委托。
2、身邊實例:
Java語言的一個非常重要的特點是平臺的無關性,對于一般的高級語言所編寫的程序,如果要在不同的平臺上運行,為了適應不同平臺所帶來的指令集及數據類型等所帶來的差異,至少需要編譯成不同的目標代碼。
Java語言通過Java虛擬機實現了平臺的無關性,虛擬機通過對底層平臺指令集及數據類型等進行統一的抽象,針對不同的平臺用不同的虛擬機進行實現,這樣Java應用程序就可以通過編譯成符合虛擬機規范的字節碼文件,而在不同的平臺上都能正確運行。
這里的虛擬機正是橋接模式一個很好的展示,它隔離了底層實現(指令/數據類型等)和高層的應用程序,對于新開發的每個Java應用程序,都只需要編譯一次;而對于一個新平臺的支持,也僅需提供一個相應的Java虛擬機,就可以使所有應用系統正確運行。
Java應用程序及虛擬機的大體結構圖如下:
3、動機簡述:
在該模式的動機中,描述了一個平臺可移植的用戶界面工具箱,在該工具箱中會有多種窗口Window類型,為了實現平臺的可移植性,把窗口的實現部分從窗口類型中抽取出來,構成一個獨立的窗口實現WindowImp類層次,從而使得抽象窗口和窗口實現都可以獨立變化,以便于支持新的窗口類型和平臺實現。
4、模式效果:
橋接Bridge模式有兩個主要效果:1)通過分離抽象部分和實現部分,使兩者可以獨立變化;2)向客戶隱藏了實現部分,從而當需要擴展/更改實現部分時,不需要重新編譯客戶代碼。
對于效果1),當抽象部分和實現部分比較多樣時,可以顯著的減少類的種類,并提高代碼的靈活性。假定高層抽象和底層實現分別有5種類型,如果不采用橋接模式,而用繼承實現,那么就需要5*5=25個類(另有一個抽象類);如果采用橋接模式,將抽象部分和實現部分分離,就只需要5+5=10個類就可以(另有兩個抽象類),兩種實現的類如以下表格中所示:
繼承方式實現:
|
Implementor
|
Imp1
|
Imp2
|
Imp3
|
Imp4
|
Imp5
|
Abstraction
|
Abs1
|
Abs1Imp1
|
Abs1Imp2
|
Abs1Imp3
|
Abs1Imp4
|
Abs1Imp5
|
Abs2
|
Abs2Imp1
|
Abs2Imp2
|
Abs2Imp3
|
Abs2Imp4
|
Abs2Imp5
|
Abs3
|
Abs3Imp1
|
Abs3Imp2
|
Abs3Imp3
|
Abs3Imp4
|
Abs3Imp5
|
Abs4
|
Abs4Imp1
|
Abs4Imp2
|
Abs4Imp3
|
Abs4Imp4
|
Abs4Imp5
|
Abs5
|
Abs5Imp1
|
Abs5Imp2
|
Abs5Imp3
|
Abs5Imp4
|
Abs5Imp5
|
橋接模式實現:
|
Implementor
|
Imp1
|
Imp2
|
Imp3
|
Imp4
|
Imp5
|
Abstraction
|
Abs1
|
通過橋接關聯
|
Abs2
|
Abs3
|
Abs4
|
Abs5
|
5、Java代碼示例:
下面代碼演示了一個支持不同平臺的圖形對象應用,圖形Shape有多種類型,如三角形正方形等,為了在不同平臺中實現圖形的繪制,把實現部分進行了分離,構成了ShapeImp類層次結構,包括在Windows中的ShapeImpWin,和Unix中的ShapeImpUnix,類結構圖如下:
代碼清單如下:
package qinysong.pattern.bridge;


public class Point ...{

private int coordinateX;
private int coordinateY;


public Point(int coordinateX, int coordinateY)...{
this.coordinateX = coordinateX;
this.coordinateY = coordinateY;
}

public String toString()...{
return "Point[x=" + coordinateX + ",y=" + coordinateY + "]";
}

public int getCoordinateX() ...{
return coordinateX;
}

public int getCoordinateY() ...{
return coordinateY;
}
}

類ShapeImp,實現接口(對應Implementor),這里只是畫一條直線
package qinysong.pattern.bridge.implement;

import qinysong.pattern.bridge.Point;


public interface ShapeImp ...{
public void drawLine(Point startPoint, Point endPoint);
}

類ShapeImpWin,實現接口的Windows實現類(對應ConcreteImplementor)
package qinysong.pattern.bridge.implement;

import qinysong.pattern.bridge.Point;


public class ShapeImpWin implements ShapeImp ...{


/** *//**
* 實現ShapeImp接口方法
* @param startPoint Point
* @param endPoint Point
*/

public void drawLine(Point startPoint, Point endPoint) ...{
System.out.println("ShapeImpWin.drawLine startPoint=" + startPoint + ",endPoint=" + endPoint);
}
}

類ShapeImpUnix,實現接口的Unix實現類(對應ConcreteImplementor)
package qinysong.pattern.bridge.implement;

import qinysong.pattern.bridge.Point;


public class ShapeImpUnix implements ShapeImp ...{


/** *//**
* 實現ShapeImp接口方法
* @param startPoint Point
* @param endPoint Point
*/

public void drawLine(Point startPoint, Point endPoint) ...{
System.out.println("ShapeImpUnix.drawLine startPoint=" + startPoint + ",endPoint=" + endPoint);
}
}

類Shape,圖形抽象類(對應Abstraction),具體類型包括三角形、正方形等
package qinysong.pattern.bridge.abstraction;

import qinysong.pattern.bridge.implement.ShapeImp;
import qinysong.pattern.bridge.ShapeImpFactory;


public abstract class Shape ...{

protected ShapeImp shapeImp;

protected void initShapeImp()...{
shapeImp = ShapeImpFactory.getShapeImp();
}

//定義圖形抽象類的接口方法
public abstract void drawShape();

}

類Triangle,三角形(對應RefinedAbstraction)
package qinysong.pattern.bridge.abstraction;

import qinysong.pattern.bridge.Point;


public class Triangle extends Shape...{

//實現抽象圖形類Shape接口方法,繪制一個三角形

public void drawShape() ...{
System.out.println("Triangle.drawShape 繪制一個三角形...");
initShapeImp();
shapeImp.drawLine(new Point(0,0), new Point(10,0));
shapeImp.drawLine(new Point(0,0), new Point(5,10));
shapeImp.drawLine(new Point(5,10), new Point(10,0));
}
}

類Square,正方形(對應RefinedAbstraction)
package qinysong.pattern.bridge.abstraction;

import qinysong.pattern.bridge.Point;


public class Square extends Shape...{

//實現抽象圖形類Shape接口方法,繪制一個正方形

public void drawShape() ...{
System.out.println("Square.drawShape 繪制一個正方形...");
initShapeImp();
shapeImp.drawLine(new Point(0,0), new Point(10,0));
shapeImp.drawLine(new Point(0,0), new Point(0,10));
shapeImp.drawLine(new Point(0,10), new Point(10,10));
shapeImp.drawLine(new Point(10,0), new Point(10,10));
}
}

類Client,橋接模式的客戶
package qinysong.pattern.bridge;

import qinysong.pattern.bridge.abstraction.Shape;
import qinysong.pattern.bridge.abstraction.Square;
import qinysong.pattern.bridge.abstraction.Triangle;


public class Client ...{


public static void main(String[] args) ...{
System.out.println("Client.main begin ..........");
Shape shape = new Square();
shape.drawShape();
Shape shape2 = new Triangle();
shape2.drawShape();

System.out.println("Client.main end ..........");
}
}

類ShapeImpFactory,工廠類,供抽象部分調用,分離實現類的創建過程
package qinysong.pattern.bridge;

import qinysong.pattern.bridge.implement.ShapeImp;
import qinysong.pattern.bridge.implement.ShapeImpWin;


public class ShapeImpFactory ...{

public static ShapeImp getShapeImp()...{
return new ShapeImpWin();
}
}
