日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

初识设计模式(装饰者模式)

發(fā)布時間:2023/12/20 asp.net 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 初识设计模式(装饰者模式) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?前言:總結(jié)這兩天學到的裝飾者模式,并用java小小的實現(xiàn)一下。書中有寫到:給愛用繼承的人一個全新的設計眼界。(ps,本文最后有個小問題待解決)

什么是裝飾者模式(Decorator Pattern)?

定義:動態(tài)地將責任附加到對象上。若要擴展功能,裝飾者提供了比繼承更有彈性的替代方案。

使用的設計原則:開放-關閉原則,類應該對擴展開放,對修改關閉。

代表:Java IO 流

類圖:

?

裝飾者模式的優(yōu)缺點?

  優(yōu)點

  • Decorator模式與繼承關系的目的都是要擴展對象的功能,但是Decorator可以提供比繼承更多的靈活性。
  • 通過使用不同的具體裝飾類以及這些裝飾類的排列組合,設計師可以創(chuàng)造出很多不同行為的組合。
  •   缺點

  • 裝飾模式會導致設計中出現(xiàn)許多小類,如果過度使用,會使程序變得很復雜,也會給使用此API的程序員造成困擾。
  • 這種比繼承更加靈活機動的特性,也同時意味著更加多的復雜性。
  • 裝飾模式是針對抽象組件(Component)類型編程。但是,如果你要針對具體組件編程時,就應該重新思考你的應用架構,以及裝飾者是否合適。當然也可以改變Component接口,增加新的公開的行為,實現(xiàn)“半透明”的裝飾者模式。在實際項目中要做出最佳選擇。
  • 采用裝飾者在實例化組件時,將增加代碼的難度。一旦使用裝飾者模式,不只需要實例化組件,還要把此組件包裝進裝飾者中。(這個問題可以使用工廠(Factory)模式和生成器(Builder)模式來解決)
  • 什么情況下使用裝飾者模式?

  • 需要擴展一個類的功能,或給一個類添加附加職責。
  • 需要動態(tài)的給一個對象添加功能,這些功能可以再動態(tài)的撤銷。
  • 需要增加由一些基本功能的排列組合而產(chǎn)生的非常大量的功能,從而使繼承關系變的不現(xiàn)實。
  • 當不能采用生成子類的方法進行擴充時。一種情況是,可能有大量獨立的擴展,為支持每一種組合將產(chǎn)生大量的子類,使得子類數(shù)目呈爆炸性增長。另一種情況可能是因為類定義被隱藏,或類定義不能用于生成子類。
  • 舉例說明

      場景:現(xiàn)在需要炒一盤菜,可以給這盤菜加多種作料,這盤菜也可以有不同作料的組合。

      實現(xiàn):(如果只有一盤菜存在,不會再有第二盤菜的情況,也可以不創(chuàng)建抽象組件,直接創(chuàng)建具體組件,抽象的裝飾類繼承具體組件。)

    • 先創(chuàng)建抽象組件 1 /** 2 * 抽象組件 一盤菜 3 */ 4 abstract class Dish{ 5 protected String name; 6 7 public String getName(){ 8 return this.name; 9 } 10 }
    • 然后創(chuàng)建具體組件 1 /** 2 * 具體組件 3 */ 4 class MeatDish extends Dish{ 5 public MeatDish(){ 6 super.name = "meatDish"; 7 } 8 }
    • 然后創(chuàng)建抽象裝飾類 1 /** 2 * 抽象裝飾類 作料 3 */ 4 abstract class Seasoning extends Dish{ 5 @Override 6 public abstract String getName(); 7 }
    • 然后創(chuàng)建抽象具體裝飾類 1 /** 2 * 具體裝飾類 鹽 3 */ 4 class Salt extends Seasoning{ 5 private Dish dish; 6 public Salt(Dish dish){ 7 this.dish = dish; 8 } 9 @Override 10 public String getName() { 11 return this.dish.getName() + " ,Salt"; 12 } 13 } 14 15 /** 16 * 具體裝飾類,雞精 17 */ 18 class ChickenPowder extends Seasoning{ 19 private Dish dish; 20 public ChickenPowder(Dish dish){ 21 this.dish = dish; 22 } 23 @Override 24 public String getName() { 25 return this.dish.getName() + " ,ChickenPowder"; 26 } 27 }
    • 然后測試 1 public static void main(String[] args){ 2 Dish dish = new MeatDish(); 3 System.out.println(dish.getName()); 4 5 dish = new Salt(dish); 6 dish = new ChickenPowder(dish); 7 System.out.println(dish.getName()); 8 }
    • 最后輸出結(jié)果

    總結(jié):

  • 裝飾者和被裝飾者擁有相同的超類
  • 你可以用一個或多個裝飾者包裝一個對象
  • 既然裝飾者和被裝飾者對象有相同的超類型,所以在任何需要原始對象(被包裝的)的場合,可以用裝飾過的對象代替它
  • 裝飾者可以在所委托被裝飾者的行為之前與/或之后,加上自己的行為,以達到特定的目的
  • 對象可以在任何時候被裝飾,所有可以在運行時動態(tài)地、不限量地用你喜歡的裝飾者來裝飾對象
  • 提問:

      問:不是說這個讓愛用繼承的人改變眼界嗎?怎么類圖還是使用的繼承?

      答:?這么做的重點在于,裝飾者和被裝飾者必須是一樣的類型,也就是有共同的超類,這是相當關鍵的地方。在這里,是利用繼承達到“類型匹配”,而不是利用繼承獲得“行為”。

      問:那么行為從哪里來?

      答:當我們將裝飾者與組件組合時,就是在加入新的行為。所得到的新行為,并不是繼承自超類,而是由組合對象得來的。如果這里依賴繼承,那么類的行為只能只能在編譯時靜態(tài)決定。換句話說,行為如果不是來自超類,就是子類覆蓋后的版本。反之,利用組合,可以把裝飾者混合著用,而且是在運行時。這樣,就可以在任何時候?qū)崿F(xiàn)新的裝飾者增加新的行為,如果依賴繼承,每當需要新行為時,還得修改現(xiàn)有的代碼。

      問:為什么Componet要設計為一個抽象類,而不是一個接口?

      答:通常裝飾者模式是采用抽象類。(有大神知道的嗎?還請不吝賜教)

    ?

    參考書籍:《Head First 設計模式》《大話設計模式》

    轉(zhuǎn)載于:https://www.cnblogs.com/yuxiaole/p/9220672.html

    總結(jié)

    以上是生活随笔為你收集整理的初识设计模式(装饰者模式)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。