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

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

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

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

一、裝飾器模式概述?

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

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

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

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

1.故事背景:機(jī)器人功能擴(kuò)展的兩種方案

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

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

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

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

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

?? 接口定義

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

?? 類實(shí)現(xiàn)

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

?? 測(cè)試代碼

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

⑵.方案二:裝飾器模式

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

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

抽象組件(Robot 接口)

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

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

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

抽象裝飾器(RobotDecorator)

abstract class RobotDecorator implements Robot {
    protected Robot robot; // 持有被裝飾的機(jī)器人對(duì)象
    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ò)組合(關(guān)聯(lián))持有原始機(jī)器人對(duì)象。它實(shí)現(xiàn)了原始功能的轉(zhuǎn)發(fā),確保裝飾時(shí)不破壞原有功能,同時(shí)為具體裝飾器提供統(tǒng)一的擴(kuò)展框架。

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

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

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

測(cè)試代碼

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  1. 變量 robot

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

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

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

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

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

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

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

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

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

// Spring Security的認(rèn)證過(guò)濾器鏈:
FilterChain filterChain = new UsernamePasswordAuthenticationFilter(
                            new BasicAuthenticationFilter(
                                new SecurityContextPersistenceFilter()
                            )
                        );
// 每個(gè)過(guò)濾器都是一個(gè)裝飾器,動(dòng)態(tài)增強(qiáng)請(qǐng)求處理能力

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

相關(guān)文章

  • 深入Java Final

    深入Java Final

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

    Java序列化原理詳解

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

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

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

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

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

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

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

    Java中PropertyDescriptor的用法及說(shuō)明

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

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

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

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

    這篇文章主要介紹了解決druid監(jiān)控頁(yè)面SQL不顯示的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    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è)計(jì)模式編程中的建造者模式與原型模式

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

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

最新評(píng)論

大宁县| 申扎县| 措美县| 涿鹿县| 武宣县| 漠河县| 玉山县| 嵊泗县| 准格尔旗| 和静县| 兴文县| 界首市| 乐东| 时尚| 西宁市| 丽江市| 含山县| 松潘县| 疏附县| 广河县| 崇仁县| 犍为县| 天气| 乌海市| 柳州市| 丰台区| 安顺市| 广元市| 平江县| 邵东县| 英山县| 延寿县| 祁门县| 五峰| 文山县| 郓城县| 张家川| 望城县| 岳阳市| 奈曼旗| 永修县|