最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java?裝飾器模式Decorator詳解及實現(xiàn)步驟

 更新時間:2025年07月17日 11:01:56   作者:magic?245  
裝飾器模式通過組合動態(tài)擴展對象功能,避免繼承導(dǎo)致的類爆炸,適用于運行時靈活添加職責的場景,廣泛應(yīng)用于Java I/O和Spring框架,提升代碼可維護性與擴展性,本文介紹Java裝飾器模式Decorator詳解及實現(xiàn)步驟,感興趣的朋友一起看看吧

在 Java 的世界里,設(shè)計模式是開發(fā)者手中的利器,它們幫助我們以更優(yōu)雅、更靈活的方式構(gòu)建軟件系統(tǒng)。今天,我們就來深入探討其中一種非常實用的設(shè)計模式 —— 裝飾器模式(Decorator Pattern)。?

一、裝飾器模式概述?

裝飾器模式屬于結(jié)構(gòu)型設(shè)計模式,它允許向一個現(xiàn)有的對象添加新的功能,同時又不改變其結(jié)構(gòu)。這就好比給一個普通的杯子加上杯蓋、杯套,讓它具備保溫、防燙等功能,而杯子本身的基本結(jié)構(gòu)并沒有發(fā)生變化。在軟件開發(fā)中,當我們需要在運行時動態(tài)地為對象添加職責,并且避免通過繼承來擴展功能帶來的類層次結(jié)構(gòu)復(fù)雜問題時,裝飾器模式就派上用場了。?

裝飾器模式主要包含以下幾個角色:?

  1. 抽象組件(Component):定義一個抽象接口,規(guī)范具體組件和裝飾器的行為。?
  2. 具體組件(Concrete Component):實現(xiàn)抽象組件接口,是被裝飾的具體對象。?
  3. 抽象裝飾器(Decorator):繼承或?qū)崿F(xiàn)抽象組件接口,持有一個抽象組件的引用,并定義一個可以動態(tài)添加職責的方法。?
  4. 具體裝飾器(Concrete Decorator):實現(xiàn)抽象裝飾器接口,負責為具體組件添加具體的功能。

二、裝飾器模式的實現(xiàn)步驟

1.故事背景:機器人功能擴展的兩種方案

在智能家居領(lǐng)域,某科技公司推出了第一代家用機器人,它具備三個核心功能:對話、唱歌和播放音樂。

// 第一代機器人:基礎(chǔ)功能
interface Robot {
    void talk();    // 對話
    void sing();    // 唱歌
    void playMusic(); // 播放音樂
}
class FirstGenerationRobot implements Robot {
    @Override
    public void talk() {
        System.out.println("機器人:你好,我能陪你聊天");
    }
    @Override
    public void sing() {
        System.out.println("機器人:正在播放《青花瓷》");
    }
    @Override
    public void playMusic() {
        System.out.println("機器人:正在播放輕音樂");
    }
}

隨著用戶需求升級,廠家希望擴展機器人的功能,讓它能夠掃地和跳舞。針對這個需求,有兩種技術(shù)方案可供選擇:

⑴.方案一:傳統(tǒng)繼承(廠家升級方案)

廠家選擇開發(fā)第二代機器人,通過繼承第一代產(chǎn)品并添加新功能:

?? 接口定義

// 基礎(chǔ)接口:第一代機器人支持的功能
interface Robot {
    void talk();
    void sing();
    void playMusic();
}

?? 類實現(xiàn)

// 第一代機器人(基礎(chǔ)實現(xiàn))
class FirstGenerationRobot implements Robot {
    @Override
    public void talk() {
        System.out.println("對話中...");
    }
    @Override
    public void sing() {
        System.out.println("正在唱歌...");
    }
    @Override
    public void playMusic() {
        System.out.println("播放音樂中...");
    }
}
// 第二代機器人:通過繼承方式擴展功能
class SecondGenerationRobot extends FirstGenerationRobot {
    public void sweep() {
        System.out.println("正在掃地...");
    }
    public void dance() {
        System.out.println("正在跳舞...");
    }
}

?? 測試代碼

public class InheritanceTest {
    public static void main(String[] args) {
        System.out.println("=== 繼承方式測試 ===");
        SecondGenerationRobot robot = new SecondGenerationRobot();
        robot.talk();
        robot.sing();
        robot.playMusic();
        robot.sweep();  // 擴展功能
        robot.dance();   // 擴展功能
    }
}

⑵.方案二:裝飾器模式

通過組合方式動態(tài)添加新功能:

以下是根據(jù)機器人例子實現(xiàn)的裝飾器模式代碼及詳細解釋:

抽象組件(Robot 接口)

interface Robot {
    void talk();   // 對話
    void sing();   // 唱歌
    void playMusic(); // 放音樂
}
  • 作用:定義機器人的基本功能,作為裝飾器模式的核心接口,規(guī)范所有機器人(包括原始機器人和裝飾后的機器人)的行為。

具體組件(第一代機器人)

class FirstGenerationRobot implements Robot {
    @Override
    public void talk() {
        System.out.println("第一代機器人:對話");
    }
    @Override
    public void sing() {
        System.out.println("第一代機器人:唱歌");
    }
    @Override
    public void playMusic() {
        System.out.println("第一代機器人:放音樂");
    }
}
  • 作用:實現(xiàn)抽象組件,是被裝飾的原始對象(第一代機器人,具有基本功能)。

抽象裝飾器(RobotDecorator)

abstract class RobotDecorator implements Robot {
    protected Robot robot; // 持有被裝飾的機器人對象
    public RobotDecorator(Robot robot) {
        this.robot = robot;
    }
    // 轉(zhuǎn)發(fā)原始功能(保持原有功能不變)
    @Override
    public void talk() {
        robot.talk();
    }
    @Override
    public void sing() {
        robot.sing();
    }
    @Override
    public void playMusic() {
        robot.playMusic();
    }
}
  • 作用:作為裝飾器的基類,繼承抽象組件接口,通過組合(關(guān)聯(lián))持有原始機器人對象。它實現(xiàn)了原始功能的轉(zhuǎn)發(fā),確保裝飾時不破壞原有功能,同時為具體裝飾器提供統(tǒng)一的擴展框架。

具體裝飾器(添加拖地和跳舞功能)

Java 中的 super 關(guān)鍵字

// 拖地裝飾器:繼承自RobotDecorator,用于為機器人添加拖地功能
class SweepFloorDecorator extends RobotDecorator {
    // 構(gòu)造函數(shù):接收被裝飾的機器人實例
    public SweepFloorDecorator(Robot robot) {
        // 通過super調(diào)用父類構(gòu)造函數(shù),保存對原始機器人的引用
        super(robot);
    }
    public void sweepFloor() { // 新增功能:拖地
        System.out.println("裝飾后:拖地");
    }
}
// 跳舞裝飾器
class DanceDecorator extends RobotDecorator {
    public DanceDecorator(Robot robot) {
        super(robot);
    }
    public void dance() { // 新增功能:跳舞
        System.out.println("裝飾后:跳舞");
    }
}

測試代碼

public class RobotDemo {
    public static void main(String[] args) {
        // 原始機器人(第一代)
        Robot robot = new FirstGenerationRobot();
        robot.talk();   // 原始功能:對話
        robot.sing();   // 原始功能:唱歌
        robot.playMusic(); // 原始功能:放音樂
        // 裝飾器擴展:添加拖地功能
        SweepFloorDecorator decoratedWithSweep = new SweepFloorDecorator(robot);
        decoratedWithSweep.talk(); // 保留原始功能
        decoratedWithSweep.sweepFloor(); // 新增功能:拖地
        // 再裝飾:添加跳舞功能
        DanceDecorator fullyDecorated = new DanceDecorator(decoratedWithSweep);
        fullyDecorated.talk(); // 保留原始功能
        // 正確調(diào)用拖地功能
        decoratedWithSweep.sweepFloor(); // 拖地功能
        // 新增功能:跳舞
        fullyDecorated.dance();
    }
}

裝飾器模式通過組合而非繼承,實現(xiàn)了運行時動態(tài)擴展對象功能,避免了繼承帶來的類爆炸問題,是處理 “對象功能擴展” 的優(yōu)雅方案。在機器人例子中,利用裝飾器模式,無需等待廠家更新(繼承方式),即可快速為第一代機器人添加拖地、跳舞功能,體現(xiàn)了模式的靈活性和實用性。

  • 繼承機制適合功能較為穩(wěn)定、擴展需求明確的場景,實現(xiàn)簡單,但不夠靈活。
  • 裝飾器模式適合需要動態(tài)組合功能、避免類爆炸的情況,雖然實現(xiàn)略復(fù)雜,但更符合開閉原則(對擴展開放,對修改關(guān)閉)。

三、流程圖和內(nèi)存圖

1.創(chuàng)建基礎(chǔ)機器人

Robot robot = new FirstGenerationRobot();
  • 創(chuàng)建第一代機器人實例,具備基礎(chǔ)功能(talk/sing/playMusic)

2.第一次裝飾:添加拖地功能

SweepFloorDecorator decoratedWithSweep = new SweepFloorDecorator(robot);
  • SweepFloorDecorator 持有對原始機器人的引用
  • 繼承了 RobotDecorator 的默認實現(xiàn)(轉(zhuǎn)發(fā)所有方法調(diào)用)

3.調(diào)用原始功能

decoratedWithSweep.talk();
  • 執(zhí)行流程:
    • decoratedWithSweep.talk() 調(diào)用 RobotDecorator 的實現(xiàn)
    • RobotDecorator 轉(zhuǎn)發(fā)給被裝飾對象:robot.talk()
    • 最終執(zhí)行 FirstGenerationRobot.talk()

4.調(diào)用新增功能

decoratedWithSweep.sweepFloor();
  • 直接調(diào)用 SweepFloorDecorator 新增的方法
  • 輸出:"裝飾后:拖地"

5.第二次裝飾:添加跳舞功能

DanceDecorator fullyDecorated = new DanceDecorator(decoratedWithSweep);
  • DanceDecorator 持有對 SweepFloorDecorator 的引用
  • 形成裝飾器嵌套結(jié)構(gòu):DanceDecorator -> SweepFloorDecorator -> FirstGenerationRobot

6.調(diào)用原始功能(多層裝飾后)

fullyDecorated.talk();
  • 執(zhí)行流程:
    • fullyDecorated.talk() 調(diào)用 RobotDecorator 的實現(xiàn)
    • 轉(zhuǎn)發(fā)給被裝飾對象:decoratedWithSweep.talk()
    • decoratedWithSweep.talk() 再次轉(zhuǎn)發(fā):robot.talk()
    • 最終執(zhí)行 FirstGenerationRobot.talk()

7.調(diào)用第一層裝飾器功能

decoratedWithSweep.sweepFloor();
  • 必須通過 decoratedWithSweep 引用調(diào)用
  • 因為 fullyDecorated 類型是 DanceDecorator,沒有直接暴露 sweepFloor() 方法

8.調(diào)用第二層裝飾器功能

fullyDecorated.dance();
  • 直接調(diào)用 DanceDecorator 新增的方法
  • 輸出:"裝飾后:跳舞"

3 個 Robot 引用的指向?qū)ο?/p>

  1. 變量 robot

    • 類型:Robot
    • 指向:FirstGenerationRobot 實例(原始機器人)
  2. SweepFloorDecorator 內(nèi)部的 robot 成員變量

    • 類型:Robot(父類 RobotDecorator 的 protected Robot robot
    • 指向:FirstGenerationRobot 實例(與變量 robot 指向同一個對象)
  3. DanceDecorator 內(nèi)部的 robot 成員變量

    • 類型:Robot(父類 RobotDecorator 的 protected Robot robot
    • 指向:SweepFloorDecorator 實例(與前兩個引用指向不同對象)

引用的內(nèi)存地址比較

Robot robot = new FirstGenerationRobot();
SweepFloorDecorator decoratedWithSweep = new SweepFloorDecorator(robot);
DanceDecorator fullyDecorated = new DanceDecorator(decoratedWithSweep);
// 內(nèi)存地址比較(假設(shè)對象內(nèi)存地址為示例值)
robot: 0x1000                  // 指向 FirstGenerationRobot
decoratedWithSweep.robot: 0x1000  // 指向 FirstGenerationRobot(與 robot 相同)
fullyDecorated.robot: 0x2000    // 指向 SweepFloorDecorator(與前兩者不同)
  • robot 和 decoratedWithSweep.robot 指向相同對象(內(nèi)存地址均為 0x1000)。
  • fullyDecorated.robot 指向不同對象(內(nèi)存地址 0x2000,即 SweepFloorDecorator 實例)。

四、實戰(zhàn)中的裝飾器模式

1. Java I/O 庫中的應(yīng)用

// 輸入流裝飾示例:
InputStream fileInput = new FileInputStream("data.txt");
InputStream bufferInput = new BufferedInputStream(fileInput);
DataInputStream dataInput = new DataInputStream(bufferInput);
// 功能動態(tài)組合:
// 基礎(chǔ)功能:FileInputStream
// 裝飾1:添加緩沖功能 BufferedInputStream
// 裝飾2:添加數(shù)據(jù)處理功能 DataInputStream

2. Spring 框架中的應(yīng)用

// Spring Security的認證過濾器鏈:
FilterChain filterChain = new UsernamePasswordAuthenticationFilter(
                            new BasicAuthenticationFilter(
                                new SecurityContextPersistenceFilter()
                            )
                        );
// 每個過濾器都是一個裝飾器,動態(tài)增強請求處理能力

到此這篇關(guān)于Java 裝飾器模式Decorator詳解及實現(xiàn)步驟的文章就介紹到這了,更多相關(guān)Java 裝飾器模式Decorator內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 深入Java Final

    深入Java Final

    本篇文章,小編將為大家介紹Java Final,有需要的朋友可以參考一下
    2013-04-04
  • Java序列化原理詳解

    Java序列化原理詳解

    這篇文章主要介紹了Java序列化原理詳解,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,感興趣的小伙伴可以參考一下
    2022-06-06
  • springboot的控制反轉(zhuǎn)和自動裝配示例代碼

    springboot的控制反轉(zhuǎn)和自動裝配示例代碼

    這篇文章主要介紹了springboot的控制反轉(zhuǎn)和自動裝配的相關(guān)知識,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-06-06
  • 如何開發(fā)一個簡單的Akka Java應(yīng)用

    如何開發(fā)一個簡單的Akka Java應(yīng)用

    這篇文章主要介紹了如何開發(fā)一個簡單的Akka Java應(yīng)用 ,幫助大家使用Java創(chuàng)建Akka項目并將其打包,感興趣的朋友可以了解下
    2020-10-10
  • JAVA簡單工廠模式(從現(xiàn)實生活角度理解代碼原理)

    JAVA簡單工廠模式(從現(xiàn)實生活角度理解代碼原理)

    本文主要介紹了JAVA簡單工廠模式(從現(xiàn)實生活角度理解代碼原理)的相關(guān)知識。具有很好的參考價值。下面跟著小編一起來看下吧
    2017-03-03
  • Java中PropertyDescriptor的用法及說明

    Java中PropertyDescriptor的用法及說明

    這篇文章主要介紹了Java中PropertyDescriptor的用法及說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Python如何使用@property @x.setter及@x.deleter

    Python如何使用@property @x.setter及@x.deleter

    這篇文章主要介紹了Python如何使用@property @x.setter及@x.deleter,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-05-05
  • 解決druid監(jiān)控頁面SQL不顯示的問題

    解決druid監(jiān)控頁面SQL不顯示的問題

    這篇文章主要介紹了解決druid監(jiān)控頁面SQL不顯示的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Java中的IO流之字符流Reader和Writer

    Java中的IO流之字符流Reader和Writer

    這篇文章主要介紹了Java中的IO流之字符流Reader和Writer,Reader : 和InputStream的唯一的區(qū)別就在于讀的數(shù)據(jù)單位不同,繼承自Reader的流都是用于向程序中輸入數(shù)據(jù),且數(shù)據(jù)的單位為字符16bit,需要的朋友可以參考下
    2023-10-10
  • 講解Java設(shè)計模式編程中的建造者模式與原型模式

    講解Java設(shè)計模式編程中的建造者模式與原型模式

    這篇文章主要介紹了Java設(shè)計模式編程中的建造者模式與原型模式,設(shè)計模式有利于團隊開發(fā)過程中的代碼維護,需要的朋友可以參考下
    2016-02-02

最新評論

宣武区| 三门县| 定州市| 澄城县| 石楼县| 齐齐哈尔市| 昌乐县| 威信县| 商河县| 河西区| 女性| 玉屏| 怀安县| 沽源县| 斗六市| 威海市| 天镇县| 郴州市| 读书| 准格尔旗| 张家川| 冕宁县| 德令哈市| 寿阳县| 和平县| 德昌县| 郸城县| 于都县| 贵南县| 南平市| 会理县| 铜梁县| 鹿邑县| 淮阳县| 西安市| 恩施市| 都昌县| 佛冈县| 黄梅县| 淳安县| 凤台县|