首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

從 Java 類庫看設計模式(三):Bridge 與 Decorator 模式實戰解析

     編輯:Java 相關知識

前言

本文聚焦兩大結構型模式:**Bridge**(橋接)與 **Decorator**(裝飾),透過 AWT Peer 架構與 IO 流類庫的經典實作,展示如何分離抽象與實作、動態組合功能。

Bridge 模式:AWT Peer 架構的抽象與實作分離

問題背景

AWT 提供跨平台視窗抽象,底層調用各作業系統原生控件。**Peer(同位體)** 充當橋接角色:

  • Abstraction:Component、Button、Menu 等 AWT 類別。
  • Implementor:ButtonPeer、MenuPeer 等 Peer 介面。
  • Concrete Implementor:Windows/Motif/Mac 等平台具體 Peer 實作。

核心結構


// 抽象層
abstract class Component {
    protected ComponentPeer peer; // 橋接參考
    public void paint(Graphics g) { peer.paint(g); } // 委派給實作
}
// 實作層
interface ComponentPeer { void paint(Graphics g); }
class WindowsButtonPeer implements ComponentPeer { ... }
class MotifButtonPeer implements ComponentPeer { ... }

關鍵設計原則

  • **分離抽象與實作**,兩者獨立演化(新增平台不動抽象,新增元件不動 Peer 介面)。
  • 常搭配 **AbstractFactory** 建立具體實作家族(如 Toolkit 建立平台 Peer)。
  • **退化 Bridge**:若僅單一實作,可省略 Implementor 介面,直接一對一關聯,不失本質。
  • 方法非一一對應:Implementor 定義**原子操作**,Abstraction 組合原子操作實作**高層邏輯**。

應用範例:報表產生器


// 實作層:原子操作
abstract class Reporter {
    abstract void addLine(String line);
    String getReport() { return header + report + trailer; }
}
class HTMLReporter extends Reporter { void addLine(String l) { report += l + "
\n"; } } class ASCIIReporter extends Reporter { void addLine(String l) { report += l + "\n"; } } // 抽象層:高層邏輯 abstract class Report { protected Reporter reporter; public Report(Reporter r) { this.reporter = r; } void addReportItem(Object item) { reporter.addLine(item.toString()); } String report() { return reporter.getReport(); } } class StockListReport extends Report { ... }

Decorator 模式:IO 流類庫的動態功能組合

問題背景

InputStream/OutputStream 僅提供基本位元組讀寫。若用繼承增加緩衝、檔案、資料型別轉換等功能,會導致**子類爆炸**(檔案+緩衝、檔案+資料、緩衝+資料...)。

Decorator 結構

  • Component:InputStream、OutputStream。
  • ConcreteComponent:FileInputStream、ByteArrayInputStream。
  • Decorator:FilterInputStream、FilterOutputStream(持有 Component 參考,預設委派)。
  • ConcreteDecorator:BufferedInputStream、DataInputStream、LineNumberInputStream。

動態組合範例

StringBuffer sb = new StringBuffer("sample");
InputStream stream = new LineNumberInputStream(
    new BufferedInputStream(
        new StringBufferInputStream(sb)
    )
);
stream.read(); stream.getLineNumber(); // 同時具備緩衝與行號功能

自訂 Decorator 4 步驟

  1. 建立繼承 FilterInputStream/FilterOutputStream 的子類。
  2. 重寫 read()/write() 實作核心邏輯。
  3. 視需要新增/重寫其他方法提供擴充功能。
  4. 確保輸入/輸出裝飾器成對出現(功能對稱)。

GUI 範例:邊框與捲軸裝飾


VisualComponent textView = new TextView();
Window window = new Window();
window.setContents(
    new BorderDecorator(
        new ScrollDecorator(textView, 500), 1
    )
);

執行時動態增減裝飾,無需修改 TextView 程式碼。

優缺點權衡

  • ✅ 解決子類爆炸,執行時動態組合,靈活性極高。
  • ❌ 物件層層包裹,**程式碼較難閱讀除錯**(如 IO 流多層嵌套)。
  • ❌ 過度使用導致大量微小物件,增加 GC 壓力。

小結

模式核心意圖關鍵結構典型場景
Bridge分離抽象與實作,雙向獨立演化Abstraction 持有 Implementor 參考AWT Peer, JDBC Driver, 報表輸出格式
Decorator動態為物件增加職責Decorator 持有 Component 參考,遞迴包裹IO 流, GUI 裝飾, Spring AOP 攔截器鏈
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved