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

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

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

      《Head First設計模式》讀書筆記 —— 裝飾者模式

      《Head First設計模式》讀書筆記
      相關代碼:Vks-Feng/HeadFirstDesignPatternNotes: Head First設計模式讀書筆記及相關代碼

      給愛用繼承的人一個全新的設計眼界

      本節用例

      Starbuzz咖啡因迅速擴展,準備更新訂單系統,以合乎其飲料供應需求

      原有類設計如下:
      原有的類設計.png

      在購買咖啡時,可以在其中加入各種調料,系統需要考慮調料部分計算費用

      第一版嘗試——枚舉所有情況

      第一版嘗試(枚舉所有情況):簡直是“類爆炸”
      第一個嘗試.png

      這是一個“維護惡夢”

      • 當有飲料或者調料價格變動,或有新調料出現……

      第二版嘗試——實例變量&繼承

      從基類Beverage下手,添加實例變量代表是否加上調料
      帶有實例變量的基類.png

      再加入子類,每個類表示菜單的一種飲料
      子類.png

      哪些需求或因素改變時會影響這個設計?

      • 調料價錢的改變會使我們更改現有代碼
      • 一旦出現新的調料,我們就需要加上新的方法,并改變超類中的cost()方法
      • 當出現新飲料時,明顯不相配的調料也會被繼承
      • 當顧客想要雙倍摩卡咖啡時,如何處理……

      回顧:組合和委托

      盡管繼承威力強大,但是它并不總是能實現最有彈性和最好維護的設計。而通過利用組合(composition)和委托(delegation)可以在運行時具有繼承行為的效果

      • 利用繼承設計子類的行為:
        • 在編譯時靜態決定
        • 所有子類都會繼承到相同的行為
      • 利用組合擴展對象的行為:
        • 動態地進行擴展
        • 可將在設計超類時還沒有想到的職責加到對象上,且不用修改原有代碼

      利用組合維護代碼:通過動態地組合對象,可以寫新的代碼添加新功能,而無需修改現有代碼,引進bug或者產生意外副作用的機會將大幅度減少

      開放-關閉原則

      代碼應該如同晚霞中的蓮花一樣地關閉(免于改變),如同晨曦中的蓮花一樣地開放(能夠擴展)

      HeadFirst設計原則4 :類應該對擴展開放,對修改關閉

      開放:通過用任何想要的行為擴展類,應對需求的改變
      關閉:已經花了很多時間確保代碼的正確,修改現有代碼可能會導致許多問題

      目標:允許類容易擴展,在不修改現有代碼的情況下,就可搭配新的行為。這樣的設計具有彈性,可以應對改變,接受新的功能來應對改變的需求

      Q:“對擴展開放,對修改關閉”聽上去很矛盾,設計如何兼顧兩者?
      A:有一些聰明的OO技巧,允許系統在不修改代碼的情況下,進行功能擴展。例如觀察者模式中,通過加入新的觀察者,我們可以在任何時候擴展主題,且不需要向主題中添加代碼。

      Q:如何將某件東西設計成可以擴展,又禁止修改?
      A:學習裝飾者模式

      Q:如何讓設計的每個部分都遵循“開放-關閉”原則
      A:通常很難辦到,這需要花費很多時間和努力。遵循開放-關閉原則,通常會引入新的抽象層次,增加代碼的復雜度。我們需要把注意力集中在設計中最有可能改變的地方,然后在那里應用開放-關閉原則

      認識裝飾者模式

      為了解決Starbuzz的問題,我們采用與上述不一樣的做法:以飲料為主體,然后在運行時以調料來“裝飾”(decorate)飲料

      例如:顧客想要摩卡和奶泡深焙咖啡

      1. 拿一個深焙咖啡(DarkRoast)對象
      2. 以摩卡(Mocha)對象裝飾它
      3. 以奶泡(Whip)對象裝飾它
      4. 調用cost()方法,并依賴委托(delegate)將調料的價錢加上去

      以裝飾者構造飲料訂單

      1. 以DarkRoast對象開始
        order1.png

        • DarkRoast繼承自Beverage,且有一個用來計算飲料價錢的cost()方法
      2. 顧客想要摩卡(Mocha),所以建立一個Mocha對象,并用它將DarkRoast對象包(wrap)起來
        order2.png

        • Mocha對象是一個裝飾者,它的類型“反映”了它所裝飾的對象(本例中就是Beverage)所謂“反映”指兩者類型一致
        • 所以Mocha也有一個cost()方法。通過多態,也可以將Mocha所包裹的任何Beverage當成是Beverage(因為Mocha是Beverage的子類型)
      3. 顧客想要奶泡(Whip),所以需要建立一個Whip裝飾者,并用它將Mocha對象包起來。
        order3.png

        • Whip是一個裝飾者,所以它也反映了DarkRoast類型,并包括一個cost方法
        • 所以被Mocha和Whip包起來的DarkRoast對象仍然是一個Beverage,任然可以具有DarkRoast的一切行為,包括調用它的cost()方法
      4. 算錢:通過調用最外圈裝飾者(Whip)的cost()就可以辦得到。Whip的cost()會先委托它裝飾的對象(也就是Mocha)計算出價錢,然后再加上奶泡的價錢
        order4.png

      小結

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

      定義裝飾者模式

      HeadFirst設計模式3-裝飾者模式

      裝飾者模式動態地將責任附加到對象上,若要擴展功能,裝飾者提供了比繼承更有彈性的替代方案

      裝飾者模式.png

      把裝飾者模式用于Starbuzz系統,得到類圖如下:
      Starbuzz.png

      注意:

      • “繼承的目的”:此處CondimentDecorator擴展自Beverage類時用到了繼承,但是這里“繼承的重點”是達到“類型匹配”的目的(因為裝飾者和被裝飾者必須是一樣的類型),而非利用繼承獲得“行為”
      • 新行為的來源:將裝飾者與組件組合時,就是在加入新的行為。即行為通過組合對象得來

      一言以蔽之:繼承超類是為了有正確的類型,而不是繼承他的行為。行為來自裝飾者和基礎組件,或與其他裝飾者之間的組合關系。

      好處:

      • 使用對象組合,可以把飲料和調料更有彈性地加以混合與匹配,十分方便
      • 組合而非繼承,實現“運行時”而非“編譯時”
      • 無需修改現有代碼

      系統實現

      代碼見開篇處倉庫地址

      Q:如果針對特定種類的具體組件,做特殊的時,這樣的設計是否恰當。(例如,針對HouseBlend打折)
      A:如果代碼寫成針對具體的組件類型,那么裝飾者就會導致程序出問題,只有在針對抽象組件類型編程時,才不會因為裝飾者而受到影響。如果的確需要針對特定的具體組件編程,就應該重新思考應用架構,以及裝飾者模式是否合適。

      Q:對于使用到飲料的某些客戶來說,會不會容易不使用到最外面的裝飾著呢?(即層層包裝時產生了很多對象,有可能最終用錯了,用的不是最外圈的)
      A:使用裝飾者模式的確必須管理更多對象,所以犯下這種編碼錯誤的機會會增加。但是裝飾者通常是用其他類似于工廠或生成器這樣的模式創建的,它們會“封裝的很好”,所以不會有這種問題。

      Q:裝飾者知道這一連串裝飾鏈條中其他裝飾者的存在嗎?
      A:裝飾者該做的事就是增加行為到被包裝對象上,當需要窺視裝飾者鏈中的每一個裝飾者事,這就超出他們的天賦了。但是可以通過其他方式實現需要借此完成的功能。

      Java I/O中的裝飾者

      JavaIO.png
      JavaIO1.png

      Java I/O引出了裝飾者模式的一個“缺點”:利用裝飾者模式,常造成設計中有大量的小類,數量眾多,可能會造成使用此API程序員的困擾

      裝飾者模式優缺點

      優點 缺點 解決
      具有為設計注入彈性的能力 有時會在設計中加入大量的小類,會導致別人不容易了解其設計方式 花點功夫對設計進行學習
      可以透明地插入裝飾者,客戶程序甚至不知道它是在和裝飾者打交道 人們在客戶代碼中依賴某種特殊類型,然后忽然導入到裝飾者,卻沒有周詳地考慮一切,就會出現問題 在插入裝飾者是,必須要小心謹慎
      / 采用裝飾者在實例化組件時,將增加代碼地復雜度。一旦使用裝飾者模式,不只需要實例化組件,還要把此組件包裝進裝飾者中 采用工廠(Factory)模式和生成器(Builder)模式來解決此問題

      總結

      OO基礎

      • 抽象
      • 封裝
      • 多態
      • 繼承

      OO原則

      • 封裝變化
      • 多用組合,少用繼承
      • 針對接口編程,不針對實現編程
      • 為交互對象之間的松耦合設計而努力
      • 對擴展開放,對修改關閉

      OO模式

      • 裝飾者模式——動態地將責任附加到對象上,若要擴展功能,裝飾者提供了比繼承更有彈性的替代方案

      要點

      • 繼承屬于擴展形式之一,但不見得是達到彈性設計的最佳方式
      • 我們的設計中,應該允許行為可以被擴展,而無需修改現有的代碼
      • 組合和委托可用于在運行時動態地加上新的行為
      • 除了繼承,裝飾者模式也可以讓我們擴展行為
      • 裝飾者模式意味著一群裝飾者類,這些類用來包裝具體組件
      • 裝飾者類反映出被裝飾的組件類型(事實上,他們具有相同的類型,都經過接口或繼承實現)
      • 裝飾者可以在被裝飾者的行為前面與/或后面加上自己的行為,甚至被裝飾者的行為整個取代掉,而達到特定的目的
      • 你可以用無數個裝飾者包裝一個組件
      • 裝飾者一般對組建的客戶是透明的,除非客戶程序依賴于組件的具體類型
      • 裝飾者會導致設計中出現許多小對象,如果過度使用,會讓程序變得很復雜
      posted @ 2025-04-29 16:29  Vcats  閱讀(98)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 美女把尿囗扒开让男人添| 福利视频在线播放| 国产精品亚洲а∨天堂2021| 久久久久国色av免费看| 国产永久免费高清在线| 久久婷婷成人综合色综合| 莫力| 午夜福利精品国产二区| 亚洲中文字幕无码专区| 成人国产精品中文字幕| 国产在线无遮挡免费观看| 成人无码区在线观看| 人人妻人人狠人人爽天天综合网 | 亚洲天堂亚洲天堂亚洲色图| 免费 黄 色 人成 视频 在 线| 中文字幕精品人妻丝袜| 色综合色国产热无码一| 日韩精品国产另类专区| 国产午夜精品理论大片| 免费国产一级 片内射老| 中国熟女仑乱hd| 一区二区中文字幕视频| 国产综合精品一区二区三区| 欧美牲交a欧美牲交aⅴ一| 国产午夜精品亚洲精品国产| 亚洲av色精品一区二区| 艳妇乳肉豪妇荡乳在线观看| 亚洲国产精品久久久久4婷婷| 狂野欧美性猛交免费视频| 久久精品国产亚洲av麻豆长发| 韩国三级+mp4| 思思99热精品在线| 日韩精品卡1卡2日韩在线| 日韩精品久久一区二区三| 麻豆国产传媒精品视频| 亚洲国产精品久久久久秋霞| 国产精品普通话国语对白露脸| 3d动漫精品一区二区三区| 中国女人熟毛茸茸A毛片| 亚洲天堂一区二区三区四区| 亚洲中文字幕成人无码|