无用的设计模式之装饰者模式
為什么80%的碼農都做不了架構師?>>> ??
前言
? ? ? 裝飾者設計模式本來是很常用的模式,常用到隨處可見,jdk的bio設計都是遵循這個模式的,偶然的機會發現,貌似jdk中bio的裝飾者模式和設計模式中的裝飾者設計模式卻有點本質上的不同,但是仔細想想,貌似bio的設計貌似還有點違背設計模式的本意,此文中把裝飾者模式說成無用,是因為他定義的這種規范的玩法,大家貌似并不遵從,反而更喜歡jdk中的用法。
類圖
????????這個類圖大家也并不陌生,具體的被裝飾的類和裝飾者都是遵循同一個規范,component,此處如果component沒有公共的定義方法,那就是妥妥的面向接口編程。看這個用法我們也能猜到怎么用,先創建被裝飾的類,然后用裝飾類去修飾被裝飾的類,然后把引用給component,調用operation的時候就把裝飾的效果顯示出來,如果需求變更,那么直接把裝飾組合出來的過程改改,其他代碼不需要改變。
jdk bio的用法
? ? ?????作為裝飾者模式的典型,他的類圖完全和上面的類圖吻合,但是我們的用法卻大大不同,我們包裝后的IO類,我們很少直接讓接口來作為引用,每一個裝飾類都帶了自己的新特性,API都不一樣了。我們想要用包裝類的功能就必須使用包裝類的引用,否則就切面了,我們能用到的只有接口的方法。他的側重是不同的包裝是不同的功能,類似readline,只有bufferedreader有,我們想用只能依靠這個包裝類,但是類本身也遵循接口,所以也能傳遞給接口,但是要損失包裝的特性。
兩種用法的對比
????????單純從軟件設計講,jdk io的設計擴展性不好,因為你選擇包裝,本來就是希望調用統一的方法,這樣對代碼的修改最小。但現實是我們如果不用具體的類無法增加新的功能。也就是說你想體現新的功能的話,后面的代碼基本要重寫。大家公有的那部分方法壓根沒有增強到,這樣寫肯定會帶來不小的隱患,但很特殊的是,他設計的是IO,一般讀取完就over,有傳遞的可能性,但是用接口傳過去后重新包裝一下又可以使用了,反正是各自包裝各自的,公有的方法都不用,這樣下來反而也沒什么影響。要選擇這么使用的話一定得慎重,用不好就帶來很多麻煩。
適合場景
????????一看類圖,大家基本就能感覺這個更像補救型的模式,就是原來的類都實現好了,現在突然要改需求,給里面的部分類的方法都增加一種或者多種功能,這樣裝飾者模式就派上用場了,直接在建造對象的地方加一段裝飾,當然這個前提都是被裝飾的類和裝飾的類都是可以估計的,遇到不可估計的情況還是直接用aop動態代理吧,不要再考慮裝飾模式。既然是補救行的,那么也是有一定要求的。
????????起碼最初的類圖是這樣的,要不然還要添加接口等等(這個肯定是不可取的),POJO的話還是用動態代理的好。
????????另外一種適合情況就是多繼承,要對中間繼承類需要增加,這種情況用裝飾者模式不會影響子類的功能。
和靜態代理的區別
? ? ? ?其實文中多次提到代理,其實在功能單一的情況下,代理和裝飾都可以,我最后想想還是從功能上做點區別,裝飾者適合新增的功能可以互相組合的情況,及裝飾類和裝飾類是可以疊加操作的,并且被裝飾的方法還是較少的,裝飾的類的個數也是較少的。靜態代理更適合類中方法很多,但是只會代理一層,出現多層代理基本就是不合理的,典型的就是datasource中用自己的connection類代理jdbc中的connection類。
最后說幾句
???? ? 其實用裝飾者模式帶來種種功能上的好處,但是一旦出現問題,你自己寫的代碼還好,要是讓純粹不知道的人走斷點找問題,那跟斷點可就費事了,所以一定留好設計文檔和把類的名字起的見字生義。
轉載于:https://my.oschina.net/xpbob/blog/662292
總結
以上是生活随笔為你收集整理的无用的设计模式之装饰者模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java并发编程-ReentrantLo
- 下一篇: [dp]leetcode 1025. D