Java中裝飾者模式與代理模式的使用

瞭解

先來說一下什麼時裝飾者模式和代理模式

裝飾者模式:顧名思義,即裝飾,打扮化妝。一個比較有意思的例子是齊天大聖72般變化,變蒼蠅變水蛇再變土地廟,這就是裝飾者模式。

代理模式:過年了你要回家,需要坐車、坐飛機,需要買票,你可以去車站買票,這可以在手機app或者網站上購票,app和網站就是代理了車站的功能,而且還能提供額外的服務,比如搶票。。

引子

有這樣一個需求,你需要設計一個咖啡計費系統,其中需要花費的有咖啡飲料和咖啡調料。

  • 分析問題
    • 需要抽象一些類來實現這個功能
    • 需要哪些類?
    • 各個類的功能是什麼?
    • 用繼承還是組合來實現?那種方法更好?

先看需要哪些類

計費接口類,其實現子類有咖啡和調料
咖啡類,其子類有各種具體的咖啡
調料類,其子類有各種具體的調料
當然需要將其子類一些共有的抽象到父類中去。

  • 看一張類圖
    這裏寫圖片描述

圖中最上面是計費類,將咖啡類和調料類的功能進行抽象,抽象出了計費功能即cost函數


然後再想,他們有哪些屬性呢?其中又有哪些是可以抽象的?

很明顯,不管咖啡還是調料都有名字和價格吧。所以這兩個屬性需要抽象,抽象到哪呢?沒錯抽象到計費接口類 Beverage(雖然翻譯是飲料)裏面。

  • 然後類圖成了這樣,當然爲了封裝可以添加一些getter和setter方法。

這裏寫圖片描述


咦,這很簡單啊,然後呢?

先來看一下,這樣設計能不能實現計費呢?
首先我們應該明確,我們是利用面向對象來實現這個咖啡系統,如果只是每一次new出一個對象,然後通過獲取價格將每一個的價格加起來?。。。如果你是這種思想,建議可以去撞豆腐了。


的確沒有完全實現,如果你是那種只喜歡和苦咖啡不用加調料的人,但是我們這個系統是面向廣大人民羣衆的,以人民的利益爲根本,不能讓他們只喝苦咖啡。
那問題就來了?如果一個人想加調料呢?相加好幾種調料呢?那又該怎麼辦呢?

  • 該怎麼辦呢,怎麼辦呢。。。

沒錯今天的主角上場了!
首先上場的是代理模式。

誰代理誰呢?咖啡代理調料?這樣就是說可以加調料還可以額外的加咖啡?一般來說喝咖啡飲料用一種而調料可以有多種。調料代理咖啡?需要咖啡並且可以額外的加調料。對嘛,這纔是正常思路呀!

再想一下,這樣可以嗎,如果調料代理咖啡,添加了一個調料,但是再添加一個調料呢?這時候調料是哪兒來的?所以說調料既需要代理咖啡也需要代理調料,那調料直接代理他們的公共父類,也就是計費接口(Beverage)不行嗎?
沒錯就這個思路!這裏利用了里氏代換原則

  • 看一下類圖,其中beverage可以設置setter和getter方法進行封裝

這裏寫圖片描述


這樣,順着思路

  1. 首先,聲明一個Beverage類型的變量。
  2. 如果用戶只想喝苦咖啡(不加調料),那隻需要實例化一個具體coffee類賦值給它(Beverage類型的變量)。
  3. 如果用戶選擇加調料,那就實例化他選擇的具體Seasoning賦值給Beverage類型的變量,再實例化具體Coffee類用具體Seasoning代理。如果再添加其他調料只需要將第一次咖啡和Seasoning的混合物(Beverage)代理給下一個調料。
  4. 順着思路,如果計算總價的話,只需要計算這種調料的價格和加調料前混合物的價格。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章