【设计模式】装饰者模式 ( 概念 | 适用场景 | 优缺点 | 与继承对比 | 定义流程 | 运行机制 | 案例分析 )
文章目錄
- I . 裝飾者模式概念
- II . 裝飾者模式適用場(chǎng)景
- III . 裝飾者模式優(yōu)缺點(diǎn)
- IV . 裝飾者模式與繼承對(duì)比
- V . 裝飾者模式相關(guān)設(shè)計(jì)模式
- VI . 裝飾者模式四個(gè)相關(guān)類
- VII . 裝飾者模式實(shí)體裝飾者類運(yùn)行機(jī)制
- VIII . 裝飾者模式定義使用流程 ( 重點(diǎn) )
- IX . 裝飾者模式 案例
I . 裝飾者模式概念
裝飾者模式概念 :
① 設(shè)計(jì)模式類型 : 結(jié)構(gòu)性 ;
② 概念 : 不改變?cè)蓄惖膶?duì)象 , 動(dòng)態(tài)地將額外的功能附加到該對(duì)象上 ;
③ 擴(kuò)展對(duì)象功能 : 這種功能擴(kuò)展方式比類繼承更加靈活 ;
④ 裝飾者模式 : 移除類中的被裝飾功能 , 將被裝飾類簡(jiǎn)化 , 區(qū)分類的核心職責(zé) 和 裝飾功能 ;
II . 裝飾者模式適用場(chǎng)景
裝飾者模式適用場(chǎng)景 :
① 功能擴(kuò)展 : 為一個(gè)類擴(kuò)展功能 , 為其添加額外的職責(zé) ; ( 強(qiáng)調(diào)擴(kuò)展 )
② 動(dòng)態(tài)添加撤銷功能 : 為一個(gè)對(duì)象動(dòng)態(tài)添加額外功能 , 同時(shí)這些被添加的功能還能被動(dòng)態(tài)撤銷 ; ( 強(qiáng)調(diào)動(dòng)態(tài) )
III . 裝飾者模式優(yōu)缺點(diǎn)
裝飾者模式優(yōu)點(diǎn) :
① 擴(kuò)展靈活 : 使用裝飾者模式 , 比繼承更加靈活 ; 使用裝飾者模式擴(kuò)展類功能 , 不會(huì)改變?cè)瓉淼念?;
② 排列組合 : 對(duì)裝飾類進(jìn)行各種排列組合 , 可實(shí)現(xiàn)不同的擴(kuò)展功能 ;
③ 開閉原則 : 裝飾者模式符合開閉原則 , 被裝飾的類 , 和裝飾類相互獨(dú)立 , 互不干擾 ;
裝飾者模式缺點(diǎn) :
① 程序復(fù)雜 : 需要編寫更多的代碼 , 生成更多的類 , 程序的復(fù)雜性增加了 ;
② 動(dòng)態(tài) / 多層 裝飾 : 動(dòng)態(tài) / 多層 裝飾一個(gè)類時(shí) , 程序更復(fù)雜 ;
IV . 裝飾者模式與繼承對(duì)比
繼承與裝飾者模式對(duì)比 :
① 繼承復(fù)雜 : 使用繼承擴(kuò)展功能 , 需要生成很多子類 , 系統(tǒng)復(fù)雜性增加 ;
② 繼承靜態(tài) : 繼承在編譯時(shí)就要確定擴(kuò)展的功能 , 是靜態(tài)的 ;
③ 裝飾者模式動(dòng)態(tài)擴(kuò)展 : 裝飾者模式可以動(dòng)態(tài)擴(kuò)展功能 , 可以在代碼運(yùn)行時(shí)擴(kuò)展功能 ;
V . 裝飾者模式相關(guān)設(shè)計(jì)模式
1 . 裝飾者模式與代理模式 :
① 注重點(diǎn) : 裝飾者模式注重動(dòng)態(tài)擴(kuò)展功能 ; 代理模式注重對(duì)對(duì)象訪問的控制 , 代理類對(duì)用戶隱藏具體細(xì)節(jié) ;
② 實(shí)例對(duì)象的使用 : 裝飾者模式將原始對(duì)象作為參數(shù)傳遞給裝飾者類構(gòu)造器 ; 代理模式中在代理類中創(chuàng)建實(shí)例對(duì)象 ;
2 . 裝飾者模式與適配器模式 : 二者都是包裝模式 ;
① 裝飾者模式 : 裝飾者模式中 , 裝飾者和被裝飾這實(shí)現(xiàn)相同的接口 , 或裝飾者是被裝飾者的子類 ;
② 適配器模式 : 適配器模式中 , 適配器和被適配的類有不同的接口 , 可能有部分接口重合 ;
VI . 裝飾者模式四個(gè)相關(guān)類
裝飾者模式四個(gè)相關(guān)類 :
① 抽象的 被裝飾者類 : 這是核心 , 后面的三個(gè)類都需要繼承該類 ;
② 實(shí)體的被裝飾者類 : 定義裝飾者模式時(shí) , 用不到 , 在客戶端被用戶調(diào)用時(shí) , 才初始化 ;
③ 抽象的裝飾者類 : 所有裝飾者類的父類 , 需要繼承抽象的被裝飾者類 ; ( 該類可選配 , 不是必須 )
④ 實(shí)體的裝飾者類 : 繼承 抽象的裝飾者類 , 在該類中維護(hù)一個(gè) 抽象裝飾者類對(duì)象 , 通過構(gòu)造函數(shù)傳入實(shí)體的被裝飾者類 , 其實(shí)現(xiàn)的 抽象的裝飾者類 方法中 , 需要調(diào)用傳入的實(shí)體對(duì)象的對(duì)應(yīng)方法 , 然后加入額外的操作 ;
VII . 裝飾者模式實(shí)體裝飾者類運(yùn)行機(jī)制
實(shí)體的裝飾者類運(yùn)行機(jī)制 :
① 核心 : 核心是 抽象的 被裝飾者類 類型 ,
② 裝飾者類型 : 實(shí)體的裝飾者類是 抽象的 被裝飾者類 類型的 ,
③ 裝飾者中維護(hù)的變量類型 : 其中維護(hù)的實(shí)例成員變量也是 抽象的 被裝飾者類 類型的 ,
④ 裝飾者模式運(yùn)行 : 裝飾者模式使用時(shí) , 先創(chuàng)建一個(gè) 抽象的 被裝飾者類 實(shí)例對(duì)象 , 創(chuàng)建一個(gè)裝飾者對(duì)象 , 通過構(gòu)造函數(shù)將上面的實(shí)例對(duì)象傳入 , 整個(gè)裝飾者模式就是為該實(shí)例對(duì)象進(jìn)行擴(kuò)展的 ;
⑤ 裝飾可循環(huán)嵌套 : 實(shí)體的被裝飾類類型是 抽象的 被裝飾者類 類型的 , 其被裝飾后 , 還是 抽象的 被裝飾者類 類型的 , 然后還可以再次裝飾 , 實(shí)體的被裝飾類的動(dòng)態(tài)功能的擴(kuò)展 , 可以被無限裝飾擴(kuò)展 ;
VIII . 裝飾者模式定義使用流程 ( 重點(diǎn) )
1 . 定義抽象被裝飾者 : 定義 抽象的 被裝飾者類 , 將其要擴(kuò)展的方法定義成抽象方法 ;
2 . 定義 ( 抽象的 ) 裝飾者類 :
① 繼承 抽象的 被裝飾者類 : 裝飾者類 繼承 抽象的 被裝飾者類 ;
② 維護(hù) 抽象的 被裝飾者類 成員 : 在該類中維護(hù)一個(gè) 抽象的 被裝飾者類 對(duì)象 , 該對(duì)象通過構(gòu)造函數(shù)傳入 ;
③ 實(shí)現(xiàn)抽象方法委托 : 裝飾者類中的抽象方法 , 需要委托給類中維護(hù)的 抽象的 被裝飾者類 對(duì)象 , 在實(shí)現(xiàn)的該抽象方法中 , 調(diào)用上面對(duì)象的對(duì)應(yīng)方法 , 然后加上要擴(kuò)展的代碼 , 這些擴(kuò)展的代碼 , 就是裝飾者模式位該對(duì)象動(dòng)態(tài)擴(kuò)展的功能 ;
3 . 定義實(shí)體對(duì)象 : 該對(duì)象是 抽象的 被裝飾者類 類型的 , 是具體的實(shí)體功能 , 要實(shí)現(xiàn)實(shí)際的大塊代碼邏輯 , 所有的操作 , 裝飾 , 都基于該實(shí)體對(duì)象類 ;
上面的裝飾者類 只關(guān)心被裝飾的方法 , 不定義其它內(nèi)容 ;
4 . 使用裝飾者模式 :
① 創(chuàng)建 抽象的 被裝飾者類 實(shí)體對(duì)象 ;
② 裝飾實(shí)體對(duì)象類 : 創(chuàng)建 抽象的 被裝飾者類 類型的裝飾者類 , 在構(gòu)造函數(shù)中 , 傳入 ① 中創(chuàng)建的 抽象的 被裝飾者類 類型的 實(shí)體對(duì)象 ;
③ 再次裝飾實(shí)體對(duì)象類 : 再次創(chuàng)建 抽象的 被裝飾者類 類型的裝飾者類 , 在構(gòu)造函數(shù)中 , 傳入 ② 中創(chuàng)建的 抽象的 被裝飾者類 類型的 裝飾者實(shí)體對(duì)象 , 這樣就實(shí)現(xiàn)了二次裝飾 ;
使用的對(duì)象類型是 抽象的 被裝飾者類 , 被裝飾的對(duì)象 , 傳入裝飾者類 , 相當(dāng)于包裝了一層 , 其對(duì)象類型還是 抽象的 被裝飾者類 , 這個(gè)包裝裝飾可以循環(huán)嵌套 ;
IX . 裝飾者模式 案例
1 . 案例需求 :
① 實(shí)體類對(duì)象 : 剛?cè)雽W(xué)的學(xué)生 , 默認(rèn)學(xué)習(xí)大學(xué)公共課 ,
② 裝飾類對(duì)象 : 如果是計(jì)算機(jī)專業(yè)的學(xué)生 , 還要繼續(xù)學(xué)習(xí)計(jì)算機(jī)專業(yè)課程 ,
③ 裝飾類對(duì)象 : 如果是音樂專業(yè)的學(xué)生 , 需要繼續(xù)學(xué)習(xí)音樂專業(yè)課程 ,
④ 二次裝飾類對(duì)象 : 如果是先學(xué)習(xí)計(jì)算機(jī) , 然后專修音樂 , 那么需要先學(xué)習(xí)計(jì)算機(jī)專業(yè)課程 , 然后學(xué)習(xí)音樂專業(yè)課程 ;
2 . 抽象的 被裝飾者類 : 抽象的學(xué)生類 , 后面的計(jì)算機(jī)專業(yè)學(xué)生裝飾者 , 音樂專業(yè)學(xué)生裝飾者都繼承該類 ;
package kim.hsl.design.decorator;/*** 裝飾者* 抽象的裝飾者* 該類也繼承 被裝飾者 的抽象類*/ public abstract class AbstractDecorator extends AbstractStudent {//聲明抽象的被裝飾者, 通過構(gòu)造器將其類型 ( 或子類類型 ) 對(duì)象傳入 , 注入實(shí)體類private AbstractStudent abstractStudent;public AbstractDecorator(AbstractStudent abstractStudent) {this.abstractStudent = abstractStudent;}/*調(diào)用實(shí)現(xiàn)的兩個(gè) 抽象裝飾者 方法實(shí)際上委托給了注入的 抽象裝飾者 類型的對(duì)象執(zhí)行的抽象裝飾者 類型的對(duì)象是其子類對(duì)象*/@Overrideprotected String studyCourses() {return this.abstractStudent.studyCourses();} }3 . 剛?cè)雽W(xué)的學(xué)生類 : 這是最普通的實(shí)體 , 是被裝飾的實(shí)體類 , 一切裝飾都是圍繞著該實(shí)體來的 ;
package kim.hsl.design.decorator;/*** 被裝飾對(duì)象* 確定的實(shí)體類*/ public class Student extends AbstractStudent {@Overrideprotected String studyCourses() {return "學(xué)習(xí)大學(xué)公共課";} }4 . 抽象的被裝飾者類 : 該類也是 抽象的被裝飾者 類 AbstractStudent 的子類 , 該類中維護(hù)了 AbstractStudent 類型的成員變量 , 通過構(gòu)造函數(shù)初始化 ; 其 studyCourses 方法需要委托給 abstractStudent 成員變量的 abstractStudent 方法 ;
package kim.hsl.design.decorator;/*** 裝飾者* 抽象的裝飾者* 該類也繼承 被裝飾者 的抽象類*/ public abstract class AbstractDecorator extends AbstractStudent {//聲明抽象的被裝飾者, 通過構(gòu)造器將其類型 ( 或子類類型 ) 對(duì)象傳入 , 注入實(shí)體類private AbstractStudent abstractStudent;public AbstractDecorator(AbstractStudent abstractStudent) {this.abstractStudent = abstractStudent;}/*調(diào)用實(shí)現(xiàn)的兩個(gè) 抽象裝飾者 方法實(shí)際上委托給了注入的 抽象裝飾者 類型的對(duì)象執(zhí)行的抽象裝飾者 類型的對(duì)象是其子類對(duì)象*/@Overrideprotected String studyCourses() {return this.abstractStudent.studyCourses();} }5 . 計(jì)算機(jī)專業(yè)學(xué)生裝飾者類 : 傳入 AbstractStudent 成員變量 , studyCourses 方法中 , 在學(xué)習(xí)公共課基礎(chǔ)上 ( 委托成員變量 ) , 還學(xué)習(xí) 計(jì)算機(jī)專業(yè)課程 ;
package kim.hsl.design.decorator;/*** 實(shí)體裝飾者類* 必須實(shí)現(xiàn)其帶參數(shù)的構(gòu)造器*/ public class ComputerStudentDecorator extends AbstractDecorator {public ComputerStudentDecorator(AbstractStudent abstractStudent) {super(abstractStudent);}@Overrideprotected String studyCourses() {return super.studyCourses() + " , 學(xué)習(xí)計(jì)算機(jī)專業(yè)課程";} }6 . 音樂專業(yè)學(xué)生裝飾者類 :
package kim.hsl.design.decorator;public class MusicStudentDecorator extends AbstractDecorator {public MusicStudentDecorator(AbstractStudent abstractStudent) {super(abstractStudent);}@Overrideprotected String studyCourses() {return super.studyCourses() + " , 學(xué)習(xí)音樂專業(yè)課程";} }7 . 測(cè)試裝飾者模式 : 其中測(cè)試了沒有裝飾的實(shí)體類 , 將其裝飾成計(jì)算機(jī)專業(yè)學(xué)生 , 將其裝飾成音樂專業(yè)學(xué)生 , 將其裝飾成計(jì)算機(jī)轉(zhuǎn)音樂專業(yè)的學(xué)生 ;
package kim.hsl.design.decorator;public class Main {public static void main(String[] args) {//剛?cè)雽W(xué)的學(xué)生Student student = new Student();System.out.println(student.studyCourses());//大二學(xué)習(xí)計(jì)算機(jī)專業(yè)課程AbstractStudent computerStudent = new ComputerStudentDecorator(student);System.out.println(computerStudent.studyCourses());//大二學(xué)習(xí)音樂專業(yè)課程AbstractStudent musicStudent = new MusicStudentDecorator(student);System.out.println(musicStudent.studyCourses());//先學(xué)計(jì)算機(jī) , 專修音樂的學(xué)生AbstractStudent computerMusicStudent = new ComputerStudentDecorator(computerStudent);System.out.println(computerMusicStudent.studyCourses());} }總結(jié)
以上是生活随笔為你收集整理的【设计模式】装饰者模式 ( 概念 | 适用场景 | 优缺点 | 与继承对比 | 定义流程 | 运行机制 | 案例分析 )的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【设计模式】外观模式 ( 概念 | 适用
- 下一篇: 【设计模式】适配器模式 ( 概念 | 适