iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 3
0

Bridge 模式定義

GoF 是如此定義的:

將抽象與實作解耦合,使它們都可以獨立地變化。

要注意到,這裡的抽象實作。必須對它們有正確的認知,才不會搞不懂上面的這句話。

  • 抽象:是指不同事物之間概念上的關聯方式

  • 實作:抽象類別與其衍生類別用來實作自己的物件

  • 解耦:指讓各種事物互相獨立地行事,或者至少明確地宣告之間的關係

裡面提到的實作,指的並非抽象類別的衍生類別唷,那些衍生類別是稱作具體類別。

回到案例

回到 DAY12 提到的形狀例子,我們的確做到了把「抽象與實作分類」,就像下圖所示。

即使有很多類別,但任何時候只需要同時處理3個物件,如圖。

程式碼實作

以下是本例使用 bridge 模式後的程式碼 (Java)。簡單起見,我們先實踐矩形的部分,圓形及其相關的繪圖 methods 的程式碼大同小異,先予以省略。

首先是 Client,他要做的事情就是取得形狀,繪畫它。

class Client {
  	public static void main() {
      	Shape myShapes[];
      	Factory myFactory = new Factory();
      	
      	// 從其他地方取得一些形狀,然後畫它
      	myShape = myFactory.getShapes();
      	for(int i = 0; i < myShapes.length; i++) {
          	myShapes[i].draw();
        }
    }
}

接下來是形狀:

abstract class Shape {
  	protected Drawing myDrawing;
  	abstract public void draw();
  	
  	// constructor
  	public Shape (Drawing drawing) {
      	// Shape 使用 Drawing
      	mydrawing = drawing;
    }
  	protected void drawLine (
      	double x1, 
      	double x2, 
    	double y1,
    	double y2
    ) {
      	myDrawing.drawLine(x1, x2, y1, y2);
    }
  
  	// Shape 的衍生類別:矩形
  	public class Rectangle extends Shape {
        private double myX1, myX2, myY1, myY2;
      	public Rectangle (
          	Drawing dp,
          	double x1,
          	double x2, 
    		double y1,
    		double y2
        ) {
          	super(dp);
          	myX1 = x1;
          	myX2 = x2;
            myY1 = y1;
          	myY2 = y2;
        }
      	public void draw() {
            // 模擬畫了四邊,成一個矩形
            drawLine(x1, y1, x2, y2);
            drawLine(x2, y1, x1, y2);
            drawLine(x1, y2, x2, y1);
            drawLine(x2, y2, x1, y1);
        }
    }
}

最後,我們看繪圖程式:

abstract class Drawing {
  	abstract public void drawLine (
      	double x1, 
      	double x2, 
    	double y1,
    	double y2
    );
  
  	// V1
  	public class V1Drawing {
      	public void drawLine (
          	double x1, 
            double x2, 
            double y1,
            double y2
        ) {
          	DP1 = new DP1();
          	DP1.dp1_line(x1, y1, x2, y2);
        }
    }
  
  	// V2
  	public class V2Drawing {
      	public void drawLine (
          	double x1, 
            double x2, 
            double y1,
            double y2
        ) {
          	DP2 = new DP2();
          	DP2.dp2_line(x1, y1, x2, y2);
        }
    }
}

Bridge 模式的特徵

以下是 bridge 模式的關鍵特徵。

項目 內容
意圖 將一組實作與另一組使用它們的物件分離
問題 一個抽象類別的衍生類別必須使用多個實作但不能出現類別數量爆炸性增長
解決方案 為所有實作定義一個介面,供抽象類別的所有衍生類別使用
參與者與協作者 Abstraction 為實作的物件定義介面,Implementor 為具體類別實作定義介面。Abstraction 的衍生類別使用 Implenentor 的衍生類別,都無須知道自己具體使用那個 ConcreteImplementor
實作 1.將實作封裝在一個抽象類別中2.在要實作的抽象的基礎類別中包含一個實作的控制碼

以下是此模式的 UML 圖。

接下來

Bridge 模式的內容就到這裡,明天我們會開始下一個設計模式:Abstract Factory 模式!明天見。


上一篇
DAY12: Bridge 模式1
下一篇
DAY14: Abstract Factory 模式
系列文
來讀設計模式:Junior developer 跟大家一起練功22
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言