<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          裝飾器模式(Decorator Pattern)該如何使用在項目?

          共 3240字,需瀏覽 7分鐘

           ·

          2021-07-11 04:47


            點擊上方“JavaEdge”,關(guān)注公眾號

          設(shè)為“星標(biāo)”,好文章不錯過!
          在實際開發(fā)中,一般你會如何給一個類或?qū)ο笮略鲂袨槟兀?/section>




          繼承


          子類在擁有自身方法的同時還擁有父類方法。但這種方案是比較靜態(tài)的,用戶無法控制新增行為的方式和時機。




          關(guān)聯(lián)


          將一個類的對象A嵌入另一個對象B,由另一個對象決定是否調(diào)用嵌入對象B的行為以便擴(kuò)展自身行為,這個嵌入的對象B就叫做裝飾器(Decorator)。

          定義



          對象結(jié)構(gòu)型模式。動態(tài)地給一個對象增加額外功能,裝飾器模式比生成子類實現(xiàn)更為靈活。

          角色





          Component 接口


          抽象構(gòu)件,定義了對象的接口,可以給這些對象動態(tài)增加功能。



          ConcreteComponent


          具體構(gòu)件,定義了具體的構(gòu)件對象,實現(xiàn)了在抽象構(gòu)件中聲明的方法,裝飾器可以給它增加額外職責(zé)(方法)。



          Decorator


          抽象裝飾類,是抽象構(gòu)件類的子類,用于給具體構(gòu)件增加職責(zé),但具體職責(zé)實現(xiàn)在其子類。



          ConcreteDecorator


          具體裝飾類,是抽象裝飾類的子類,負(fù)責(zé)向構(gòu)件添加新的職責(zé)。

          代碼案例



          窗口 接口

          public interface Window {
            // 繪制窗口 public void draw();   // 返回窗口的描述 public String getDescription();}

          無滾動條功能的簡單窗口實現(xiàn)

          public class SimpleWindow implements Window {
          public void draw() { // 繪制窗口 }
          public String getDescription() { return "simple window"; }}

          抽象裝飾類,注意實現(xiàn)Window接口

          public abstract class WindowDecorator implements Window {    // 被裝飾的Window    protected Window decoratedWindow;
          public WindowDecorator (Window decoratedWindow) { this.decoratedWindow = decoratedWindow; } @Override public void draw() { decoratedWindow.draw(); }
          @Override public String getDescription() { return decoratedWindow.getDescription(); }}

          第一個具體裝飾器,添加垂直滾動條功能

          public class VerticalScrollBar extends WindowDecorator {  public VerticalScrollBar(Window windowToBeDecorated) {    super(windowToBeDecorated);  }
          @Override public void draw() { super.draw(); drawVerticalScrollBar(); }
          private void drawVerticalScrollBar() { // Draw the vertical scrollbar }
          @Override public String getDescription() { return super.getDescription() + ", including vertical scrollbars"; }}

          第二個具體裝飾器,添加水平滾動條功能

          public class HorizontalScrollBar extends WindowDecorator {  public HorizontalScrollBar (Window windowToBeDecorated) {    super(windowToBeDecorated);  }
          @Override public void draw() { super.draw(); drawHorizontalScrollBar(); }
          private void drawHorizontalScrollBar() { // Draw the horizontal scrollbar }
          @Override public String getDescription() { return super.getDescription() + ", including horizontal scrollbars"; }}

          優(yōu)點



          裝飾模式以對用戶透明的方式動態(tài)給一個對象附加功能,用戶不會覺得對象在裝飾前、后有何不同。裝飾模式可在無需創(chuàng)造更多子類情況下,擴(kuò)展對象的功能。

          與繼承相比,關(guān)聯(lián)優(yōu)勢在于不破壞類的封裝性,而且繼承是一種耦合度較大的靜態(tài)關(guān)系,無法在程序運行時動態(tài)擴(kuò)展。

          可通過動態(tài)方式擴(kuò)展一個對象的功能,通過配置文件可以在運行時選擇不同裝飾器,從而實現(xiàn)不同行為。

          在軟件開發(fā)階段,關(guān)聯(lián)關(guān)系雖然不會比繼承關(guān)系減少編碼量,但到了軟件維護(hù)階段,由于關(guān)聯(lián)關(guān)系使系統(tǒng)具有較好的松耦合性,所以更容易維護(hù)。

          通過使用不同具體裝飾類以及這些裝飾類的排列組合,可以創(chuàng)造出很多不同行為的組合。可以使用多個具體裝飾類來裝飾同一對象,得到功能更強大的對象。

          具體構(gòu)件類與具體裝飾類可以獨立變化,用戶可以根據(jù)需要增加新的具體構(gòu)件類、具體裝飾類,在使用時再對其進(jìn)行組合,原有代碼無須改變,符合“開閉原則”。

          缺點



          產(chǎn)生很多小對象,這些對象區(qū)別在于它們之間相互連接的方式不同,而非類或?qū)傩灾挡煌瑫r還將產(chǎn)生很多具體裝飾類。這些裝飾類和小對象的產(chǎn)生將增加系統(tǒng)的復(fù)雜度,加大學(xué)習(xí)與理解的難度。

          比繼承更靈活,也意味著比繼承更易出錯,排查也更困難,對于多次裝飾的對象,調(diào)試時尋找錯誤可能需要逐級排查,較為煩瑣。

          適用場景



          • 在不影響其他對象的情況下,以動態(tài)、透明的方式給單個對象添加職責(zé)

          • 需要動態(tài)地給一個對象增加功能,這些功能也可以動態(tài)地被撤銷

          • 當(dāng)不能采用繼承的方式對系統(tǒng)進(jìn)行擴(kuò)充或者采用繼承不利于系統(tǒng)擴(kuò)展和維護(hù)時

          不能采用繼承的場景:

          • 系統(tǒng)存在大量獨立擴(kuò)展,為支持每一種組合將產(chǎn)生大量的子類,使得子類數(shù)目呈爆炸性增長

          • 類定義不能繼承(如final類)


          擴(kuò)展



          一個裝飾類的接口必須與被裝飾類的接口保持相同,對于客戶端來說無論是裝飾之前的對象還是裝飾之后的對象都可以一致對待。
          盡量保持具體構(gòu)件類的輕量,也就是說不要把太多的邏輯和狀態(tài)放在具體構(gòu)件類中,可以通過裝飾類對其進(jìn)行擴(kuò)展。

          裝飾模式可分為:

          • 透明裝飾模式
            要求客戶端完全針對抽象編程,裝飾模式的透明性要求客戶端程序不應(yīng)該聲明具體構(gòu)件類型和具體裝飾類型,而應(yīng)該全部聲明為抽象構(gòu)件類型。

          • 半透明裝飾模式
            允許用戶在客戶端聲明具體裝飾者類型的對象,調(diào)用在具體裝飾者中新增的方法。

          往期推薦


          擁抱Kubernetes,再見了Spring Cloud

          百度二面:一個線程OOM了,其它線程還能運行嗎?

          這一次徹底搞懂JDK動態(tài)代理

          Iterator迭代器到底是什么?


          目前交流群已有 800+人,旨在促進(jìn)技術(shù)交流,可關(guān)注公眾號添加筆者微信邀請進(jìn)群



          喜歡文章,點個“在看、點贊、分享”素質(zhì)三連支持一下~

          瀏覽 29
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  天天曰天天干 | 日韩熟妇视频 | 青娱乐最新视频 | 久久亚洲国产 | 色先锋AV|