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

Java 裝飾器模式深度解析:動態擴展對象職責,替代繼承爆炸

     編輯:Java 相關知識

裝飾器模式在不修改原類、不使用繼承的情況下,動態為對象添加職責。本文以「房子裝修」為例,展示如何通過組合替代繼承,實現車庫、廚房等功能的靈活疊加,並解析 IO 流體系中的經典應用。

模式四大角色

  • Component(抽象構件):定義對象統一介面 AbstractHouse
  • ConcreteComponent(具體構件):被裝飾的核心對象 GenericHouse
  • Decorator(抽象裝飾角色):持有 Component 引用,實現 Component 介面 Master
  • ConcreteDecorator(具體裝飾角色):實際添加職責 Garage、Kitchen

核心代碼實現

// 抽象構件
interface AbstractHouse {
    void doSomething();
}

// 具體構件
class GenericHouse implements AbstractHouse {
    public void doSomething() {
        System.out.println("具體構件:房子可居住,遮風擋雨");
    }
}

// 抽象裝飾角色:持有被裝飾對象
class Master implements AbstractHouse {
    protected AbstractHouse house;
    public Master(AbstractHouse house) { this.house = house; }
    public void doSomething() {
        System.out.println("裝飾角色:持有被裝飾對象");
        house.doSomething(); // 委派核心行為
    }
}

// 具體裝飾:車庫
class Garage extends Master {
    public Garage(AbstractHouse house) { super(house); }
    public void doSomething() {
        super.doSomething();
        System.out.println("具體裝飾:加裝車庫,可停車");
    }
}

// 具體裝飾:廚房
class Kitchen extends Master {
    public Kitchen(AbstractHouse house) { super(house); }
    public void doSomething() {
        super.doSomething();
        System.out.println("具體裝飾:加裝廚房,可做飯");
    }
}

// 客戶端:動態組合
public class Demo {
    public static void main(String[] args) {
        AbstractHouse house = new GenericHouse();
        
        // 疊加裝飾:先加車庫,再加廚房
        house = new Kitchen(new Garage(house));
        house.doSomething();
        /* 輸出:
           裝飾角色:持有被裝飾對象
           具體構件:房子可居住,遮風擋雨
           具體裝飾:加裝車庫,可停車
           具體裝飾:加裝廚房,可做飯
        */
    }
}

經典應用:Java IO 流體系

JDK IO 是裝飾器模式教科書級應用:

// 节点流(具體構件)
FileInputStream fis = new FileInputStream("a.txt");

// 疊加裝飾器
BufferedInputStream bis = new BufferedInputStream(fis);      // 緩衝
DataInputStream dis = new DataInputStream(bis);              // 基本類型讀取
ObjectInputStream ois = new ObjectInputStream(dis);          // 對象反序列化

// 每層裝飾器增強特定能力,組合靈活,無繼承爆炸

裝飾器 vs 繼承 vs 代理

維度繼承裝飾器代理
關係is-ahas-a(組合)has-a
擴展時機編譯期靜態運行期動態運行期動態
目的特化行為增強職責控制訪問/隱藏細節
疊加單繼承受限無限疊加通常單層

適用場景

  • 需要在不影響其他對象的情況下,給單個對象動態添加職責
  • 職責可疊加、可撤銷(如權限校驗、日誌記錄、壓縮加密、事務管理)
  • 無法使用繼承(最終類、類爆炸、需組合多種行為)

實戰提示

  1. 裝飾器必須實現與被裝飾對象相同介面,保證客戶端透明使用
  2. 避免在裝飾器中依賴具體構件類型(面向介面編程)
  3. 大量裝飾器時考慮 Builder 模式簡化構建鏈
  4. Spring AOP 本質上是動態代理,但思想與裝飾器高度相似

裝飾器模式是「組合優於繼承」原則的典範實踐,善用它能構建極具彈性的系統架構。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved