<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Java設計模式學習記錄-裝飾模式

      前言

      裝飾模式也是一種結構型模式,主要是目的是相對于類與類之間的繼承關系來說,使用裝飾模式可以降低耦合度。JDK中有不少地方都使用到了裝飾模式,例如Java的各種I/O流,javax.swing包中一些圖形界面構件功能的增強等地方都運用了裝飾模式。 

      裝飾模式

      定義

      裝飾模式的定義是:在不改變原類文件以及不使用繼承的情況下,動態的擴展一個對象的功能。裝飾模式是通過創建一個包裝對象來實現的,也就是用裝飾來包裹真實的對象。

      舉例

      還是老規矩,舉例說明,在給親朋好友過生日時會買生日蛋糕,然后生日蛋糕又有各種各樣的輔料來進行裝飾,例如:奶油,水果,芝士,巧克力等等。如果沒有這些輔料來進行裝飾,就是普通的雞蛋糕。所以我們可以把做蛋糕的這個過程來用代碼實現出來:

      首先定義蛋糕接口

      /**
       * 蛋糕
       */
      public interface CakeGoods {
      
          /**
           * 展示蛋糕
           */
          void showCake();
      
          /**
           * 展示價格
           */
          BigDecimal showPrice();
      }

      具體的雞蛋糕

      /**
       * 雞蛋糕
       */
      @Data
      public class SpongeCake implements CakeGoods{
      
          //蛋糕名稱
          private String name;
          //蛋糕價格
          private BigDecimal price;
      
          public SpongeCake(String name,BigDecimal price){
      
              this.name = name;
              this.price = price;
          }
      
          /**
           * 展示蛋糕
           */
          @Override
          public void showCake() {
      
              System.out.println("的"+this.name+"蛋糕");
      
          }
      
          /**
           * 展示價格
           */
          @Override
          public BigDecimal showPrice() {
      
              return this.price;
          }
      }

      輔料的抽象類

      /**
       * 輔料的抽象類
       */
      public abstract class Decorator implements CakeGoods{
      
          private CakeGoods cakeGoods;
      
          public void setCakeGoods(CakeGoods cakeGoods){
              this.cakeGoods = cakeGoods;
          }
      
          /**
           * 展示蛋糕
           */
          @Override
          public void showCake() {
              cakeGoods.showCake();
          }
      
          /**
           * 展示價格
           */
          @Override
          public BigDecimal showPrice() {
              return cakeGoods.showPrice();
          }
      }

      水果

      /**
       * 水果
       */
      public class Fruits extends Decorator {
          /**
           * 展示蛋糕
           */
          @Override
          public void showCake() {
              System.out.print("加水果");
              super.showCake();
          }
      
          /**
           * 展示價格
           */
          @Override
          public BigDecimal showPrice() {
              return new BigDecimal(20.00).add(super.showPrice());
          }
      }

      奶油

      /**
       * 奶油
       */
      public class Cream extends Decorator {
          /**
           * 展示蛋糕
           */
          @Override
          public void showCake() {
              System.out.print("加奶油");
              super.showCake();
          }
      
          /**
           * 展示價格
           */
          @Override
          public BigDecimal showPrice() {
              return new BigDecimal(15.00).add(super.showPrice());
          }
      }

      測試

      public class Tests {
      
          public static void main(String[] args) {
              
              //制造雞蛋糕
              CakeGoods cakeGoods = new SpongeCake("生日祝福",new BigDecimal(50));
      
              Decorator cream = new Cream();
              Decorator fruits = new Fruits();
      
              //加奶油
              cream.setCakeGoods(fruits);
              //加水果
              fruits.setCakeGoods(cakeGoods);
              
              //展示
              cream.showCake();
              System.out.println("的價格是:"+cream.showPrice()+"元");
          }
      
      }

      運行結果:

      加奶油加水果的生日祝福蛋糕
      的價格是:85元

       上面的這個蛋糕制造的例子使用的就是裝飾模式,在為雞蛋糕SpongeCake進行擴展的時候并沒有影響它原來的類的結構,也沒有使用繼承的關系,最終卻達到了裝飾的目的。下面我們來分析一下裝飾模式具體是由那幾部分組成。

      裝飾模式的結構

      裝飾模式的結構圖如上所示,主要由以下幾個角色組成。

      抽象構件角色:(上圖的CakeGoods)定義一個抽象接口,以規范準備接受裝飾的對象,想當于Java中的IO流里的InputStram/OutputStream和Reader/Writer。

      具體的構件角色:(上圖的SpongeCake)定義一個將要接受裝飾的類,相當于I/O流里面的FileOutputStream和FileInputStream。

      裝飾角色:(上圖的Decorator)定義一個持有抽象構件角色的引用,并定義一個與抽象構件一直的接口。相當于I/O里面的FilterOutputStream和FilterInputStream。

      具體的裝飾角色:(上圖的Fruits和Cream)負責各構件角色對象加上相應的裝飾品,相當于I/O流里的BufferedOutputStream、BufferedInputStream。

      在使用的時候,必須擴展CakeGoods的功能,但是我們是通過Fruits和Cream來對CakeGoods進行擴展的,所以相對于CakeGoods來說無需知道Decorator的存在,就能擴展功能了。

      總結

      裝飾模式的優點

      1. 對于擴展一個對象的功能,裝飾模式比繼承更加靈活性,不會導致類的個數急劇增加。例如上面的例子如果想增加一個棗糕或是一個巧克力輔料,無需修改現有代碼,只需將棗糕作為CakeGoods的一個子類,以及Decorator的一個子類即可。
      2. 可以動態的擴展一個對象的功能。
      3. 可以對一個對象進行多次裝飾,通過使用不同的具體裝飾類以及這些裝飾類的排列組合,可以創造出很多不同行為的組合,得到功能更為強大的對象。
      4. 具體構件類與具體裝飾類可以獨立變化,用戶可以根據需要增加新的具體構件類和具體裝飾類,原有類庫代碼無須改變,符合“開閉原則”。

      裝飾模式的缺點

      1. 使用裝飾模式進行系統設計時將產生很多小對象,這些對象的區別在于它們之間相互連接的方式有所不同,而不是它們的類或者屬性值有所不同,大量小對象的產生勢必會占用更多的系統資源,在一定程序上影響程序的性能。
      2. 裝飾模式提供了一種比繼承更加靈活機動的解決方案,但同時也意味著比繼承更加易于出錯,排錯也很困難,對于多次裝飾的對象,調試時尋找錯誤可能需要逐級排查,較為繁瑣。

      適用場景

      在不影響其他對象的情況下,以動態、透明的方式給單個對象添加職責。

      當不能采用繼承的方式對系統進行擴展或者采用繼承不利于系統擴展和維護時可以使用裝飾模式。不能采用繼承的情況主要有兩類:第一類是系統中存在大量獨立的擴展,為支持每一種擴展或者擴展之間的組合將產生大量的子類,使得子類數目呈爆炸性增長;第二類是因為類已定義為不能被繼承(如Java語言中的final類)。

       

      加油,給自己打氣,克服惰性!!!

       

       

       

       

       

      想了解更多的設計模式請查看Java設計模式學習記錄-GoF設計模式概述

       

       

       

       

       

      posted @ 2018-08-12 17:31  紀莫  閱讀(818)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲高清aⅴ日本欧美视频| 91精品国产老熟女在线| 新化县| 美欧日韩一区二区三区视频| 张家川| 国产一区二区三区黄色片| 26uuu另类亚洲欧美日本| 丁香五月亚洲综合在线国内自拍| 中文字幕乱偷无码av先锋蜜桃| chinese性内射高清国产| 欧美一区二区三区激情| 国产乱子伦无套一区二区三区| 久久精品夜夜夜夜夜久久| 国产AV影片麻豆精品传媒 | 贵港市| 日韩av综合中文字幕| 国产精品无码免费播放| 日本系列亚洲系列精品| 激情五月日韩中文字幕| 人妻人人澡人人添人人爽人人玩 | 国产精品爱久久久久久久| 激情五月日韩中文字幕| 春色校园综合人妻av| 亚洲的天堂在线中文字幕| 在线 欧美 中文 亚洲 精品| 国产丝袜在线精品丝袜不卡| 日韩大片看一区二区三区| 香蕉亚洲欧洲在线一区| 国产免费午夜福利蜜芽无码| 国产成人精品a视频一区| 亚洲欧美综合中文| 欧美三级中文字幕在线观看| 婷婷开心深爱五月天播播| 国产偷国产偷亚洲高清人| 激情久久av一区av二区av三区| 国产一区二区三区粉嫩av| 欧美白妞大战非洲大炮| 中文字幕无码久久精品| 老熟妇欲乱一区二区三区| 亚洲国产精品久久久久婷婷图片| 年日韩激情国产自偷亚洲|