Bridge 模式


您現在打算開發一個烏龜繪圖程式,烏龜會在平面上移動,您想將烏 龜所經過的路線都畫下來,繪圖時所使用的API可能是Java 2D API,或者是 Open 2D API,您用它們分別實現了JavaDuke與OpenDuke類別:


如果今天您要繼承擴充,讓烏龜變成海龜,可以在海洋中自由活動,您擴充了Turtle成為Turtle3D,並再分別使用Java 2D API與Open 2D API實作如下:


因 為您的烏龜實作時,都依賴於特定的API,應用程式若持續演化下去,與特定 API 的相依性就越大,最後無法自拔!例如,如果Open 2D API作了介面的調整,您所有依賴Open 2D API的實作就得一一找出相關的部份進行修正。或者是如果將來您想要使用別的2D API,顯然地就得重寫所有的實現類別,而不能簡單地抽換。

您應該辨識出實作介面時,相依於特定API的部份,為它們製定介面,讓實作依賴於介面:


這麼一來,您的應用程式與相依的2D API都可以獨立地演化,您可以抽換應用程式所使用的2D API,如果打算使用新的2D API,只需使用該2D API實作Drawing介面就可以了。

以Java程式來示範的話:
interface Turtle {
void move();
void turn();
}

interface Drawing {
void drawImage(String image);
void drawLine();
void turnImage(String image);
void rotateImage(String image);
}

class JavaDrawing implements Drawing {
public void drawImage(String image) {
System.out.println("Java 2D 畫 " + image);
}
public void drawLine() {
System.out.println("Java 2D 畫線 ");
}
public void turnImage(String image) {
System.out.println("Java 2D 轉 " + image);
}
public void rotateImage(String image) {
System.out.println("Java 2D 翻 " + image);
}
}

class Duke implements Turtle {
private String image = "Duke";
private Drawing drawing;

Duke(Drawing drawing) {
this.drawing = drawing;
}

public void move() {
System.out.println("計算出目的地位置");
drawing.drawImage(image);
drawing.drawLine();
}
public void turn() {
drawing.rotateImage(image);
drawing.drawImage(image);
}
}

public class Main {
public static void main(String[] args) {
Turtle turtle = new Duke(new JavaDrawing());
turtle.move();
turtle.turn();
}
}

以Python來示範的話:
class JavaDrawing:
def drawImage(self, image):
print("Java 2D 畫 " + image)
def drawLine(self):
print("Java 2D 畫線 ")
def turnImage(self, image):
print("Java 2D 轉 " + image)
def rotateImage(self, image):
print("Java 2D 翻 " + image)

class Duke:
def __init__(self, drawing):
self.image = "Duke"
self.drawing = drawing
def move(self):
print("計算出目的地位置")
self.drawing.drawImage(self.image)
self.drawing.drawLine()
def turn(self):
self.drawing.rotateImage(self.image)
self.drawing.drawImage(self.image)

turtle = Duke(JavaDrawing())
turtle.move()
turtle.turn()

Bridge模式的目的,在於將抽象與實現分離,使兩者都可以獨立地演 化。這邊所謂的抽象,指的是指應用程式行為定義的演化,而實現指的是應用程式實作時,所需使用的特定API或平台。

以UML來表示Bridge模式的結構:


簡單地說,Bridge模式的重點在於,對Abstraction的實作,不應該依賴於特定API或平台,應 辨識出Implementor,透過Implementor來橋接特定API或平台實現。