大家好,是每周在里陪你進的網(wǎng)管~本次我們續(xù)填坑,一下裝飾模式。上文章我們過裝飾器代理模式特殊應用而且很多說中間件用裝飾器式實現(xiàn)的有的人說用職責鏈現(xiàn)的,那這篇文章們就來一看看他們異同。什是裝飾器飾器模式Decorator Pattern)也叫作包裝器式(Wrapper Pattern),指在不改變有對象的礎上,動地給一個象添加一額外的職。就增加能來說,飾器模式比生成子更為靈活屬于結構設計模式給對象添新行為最單直觀的法就是擴本體對象通過繼承方式達到的。但是用繼承不避免地有下兩個弊:繼承是態(tài)的,在譯期間就經(jīng)確定,法在運行改變對象行為。子只能有一父類,當要添加的功能太多,容易導類的數(shù)量增。而使裝飾器模,我們通將現(xiàn)有對放置在實了相同一接口的包器對象中動態(tài)地向有對象添新行為。包裝器中行我們代的擴展,助于重用能并且不修改現(xiàn)有象的代碼符合“開原則”。里被放置包裝對象“現(xiàn)有對”通常會叫做“組”(Component),而包裝組件的裝器對象是我們常的“裝飾”(Decorator),因為裝飾器會件實現(xiàn)相接口,故戶端無法別兩者的異,也就需要在增裝飾器時客戶端調代碼進行改了。從面關于裝器模式的述中 ,會感覺他跟理模式很。這是因他們本來結構上也乎一樣,飾器算是理的一個殊應用--裝飾器模的一個特是可以嵌多層裝飾,相當于代理再加理。不過理強調的對本體對的訪問控,而裝飾是用來對地進行增,兩者在用目的上一樣。上裝飾器模的用處特用文字描了這么多下面我們 UML 類圖展示下它的結,讓我們寫代碼前模式中的個角色有更清晰的識。裝飾的結構用 UML 類圖表示裝器模式的構如下:圖中可以到裝飾器式中主要如下幾個色:客戶:會用多裝飾器來裝組件,后調用裝好的包裝的方法,動執(zhí)行。件接口:Component 聲明裝飾器象和被裝的組件對要實現(xiàn)的用接口。件實現(xiàn):體的組件現(xiàn)類它的 Operation 方法中定了組件的礎行為,飾類可以強這些行?;A裝類:擁有個指向被裝對象的員變量。自己的 Operation 方法中調用裝飾對象 Operation 方法具體裝飾類:寫父類的 Operation 方法實現(xiàn)強邏輯。圖里已經(jīng)出了要實的主要邏,第四步基礎裝飾并不需要定存在,全可以由體裝飾類持有對被飾對象的用,并實增強邏輯這樣一來體的結構更簡單一。注意:中的方法在代碼實里可自己義,不需完全跟圖給出的方名一樣。們可以跟節(jié)代理模的 UML 類圖做個對比,兩在結構上常相似,其是省略 BaseDecorator 這一層后在結構上本上是一一樣,這我們一直強調的--"裝飾器是代理模式特殊應用" 的一個論據(jù)。下面們看一下現(xiàn)裝飾器式的代碼版,本文提供了 Go 語言實現(xiàn)一個簡裝飾器模的代碼模。裝飾器式代碼實清楚了裝器模式結的組成后再來寫代就會清晰多,接下我們演示下用裝飾模式實現(xiàn)強游戲主的一個例。首先我定義一個戲主機的品接口,就是上面圖中組件裝飾器的共接口。//?PS5?產(chǎn)品接type?PS5?interface?{?StartGPUEngine()?GetPrice()?int64}然后我們供一個基的產(chǎn)品實類作為裝器模式中組件。//?CD?版?PS5主機"本文使用的完整運行源碼公眾號「管叨bi叨」發(fā)送【計模式】可領取"type?PS5WithCD?struct{}func?(p?PS5WithCD)?StartGPUEngine()?{?fmt.Println("start?engine")}func?(p?PS5WithCD)?GetPrice()?int64?{?return?5000}這里給出的是個 CD 版的游戲機,平時游戲的同都會知道一般還會數(shù)字版的機,價格便宜點,種情況我可以提供個數(shù)字版戲主機的現(xiàn)作為組實現(xiàn)類。//?PS5?數(shù)字版機type?PS5WithDigital?struct{}func?(p?PS5WithDigital)?StartGPUEngine()?{?fmt.Println("start?normal?gpu?engine")}func?(p?PS5WithDigital)?GetPrice()?int64?{?return?3600}那么除了這兩種基的產(chǎn)品類,廠商一還會開發(fā)種主題限配色的主、增加了件配置的機等等,兩種在價上肯定會基礎版有不一樣,對這種層的擴展我可以使用飾器來實,避免對礎組件類更改。下是用兩個飾器實現(xiàn) Plus 版和主題配色版的個增強。"本文使用完整可運源碼去公號「網(wǎng)管bi叨」發(fā)送【設計式】即可取"http://?Plus?版的裝飾func?(p?*PS5MachinePlus)?SetPS5Machine(ps5?PS5)?{?p.ps5Machine?=?ps5}func?(p?PS5MachinePlus)?StartGPUEngine()?{?p.ps5Machine.StartGPUEngine()?fmt.Println("start?plus?plugin")}func?(p?PS5MachinePlus)?GetPrice()?int64?{?return?p.ps5Machine.GetPrice()?+?500}//?主題色版的裝器type?PS5WithTopicColor?struct?{?ps5Machine?PS5}func?(p?*PS5WithTopicColor)?SetPS5Machine(ps5?PS5)?{?p.ps5Machine?=?ps5}func?(p?PS5WithTopicColor)?StartGPUEngine()?{?p.ps5Machine.StartGPUEngine()?fmt.Println("尊貴的主題主機,GPU啟動")}func?(p?PS5WithTopicColor)?GetPrice()?int64?{?return?p.ps5Machine.GetPrice()?+?200}根據(jù)裝飾器式的特點兩個增強可以疊加一起,組出即高配題限定版機...... 呃,是不是有某游戲大每年發(fā)新時給你的覺了,就不出第二,每年給多發(fā)幾個定配色、級下屏幕說的就是 XXX(各位自己論里腦補下)好了在客戶端們把裝飾和組件組起來就能得一款高主題限定主機......"本文使用的整可運行碼去公眾「網(wǎng)管叨bi叨」發(fā)送【設計模】即可領"func?main()?{?ps5MachinePlus?:=?PS5MachinePlus{}?ps5MachinePlus.SetPS5Machine(PS5WithCD{})?//?ps5MachinePlus.SetPS5Machine(PS5WithDigital{})?//?可以在更主機?ps5MachinePlus.StartGPUEngine()?price?:=?ps5MachinePlus.GetPrice()?fmt.Printf("PS5?CD?豪華Plus版,價?%d?元\n\n",?price?ps5WithTopicColor?:=?PS5WithTopicColor{}?ps5WithTopicColor.SetPS5Machine(ps5MachinePlus)?ps5WithTopicColor.StartGPUEngine()?price?=?ps5WithTopicColor.GetPrice()?fmt.Printf("PS5?CD?豪華Plus?經(jīng)典主題配版,價?%d?元\n",?price}裝飾器和個模式的別裝飾器代理在結上類似,行為上跟責鏈模式似,現(xiàn)在們總結一他們之間區(qū)別裝飾模式 VS 代理模式裝飾器模就是代理式的一個殊應用。飾器模式調自身功的擴展。理模式強對代理過的控制。飾器 VS 職責鏈模式裝飾器職責鏈在為上看都多個單元行組合完邏輯處理但是裝飾注重給某東西添加展,最終得到一個品。而職鏈更強調步驟完成個流程,像是一個務鏈表,且與裝飾模式不同是,職責可以隨時止。舉個子來說,對 OA 系統(tǒng)請假批這個場,假設員請假需要到組長、監(jiān)和經(jīng)理批準才行在這種情下,使用飾器模式現(xiàn)的話無您的請假前面的環(huán)被批準還被拒絕,個鏈條都會中斷,終我們會到三個級審批人對請的全部饋。而使職責鏈模的話,在個階段,個審批人有權批準拒絕。如請求在任級別被拒,那么整流程就會束,請求會繼續(xù)流到下一個別的審批那里。所看到這里你覺得像 Web 框架的中間這種東西該拿職責還是裝飾實現(xiàn)呢?結裝飾器式有不少點,它是承的有力充,比繼靈活,在改變原有象的情況,動態(tài)地一個對象展功能,插即用。過使用不裝飾類及些裝飾類排列組合可以實現(xiàn)同效果,全遵循程設計的“閉原則”但裝飾器使用必將給程序帶更高的復性,更低可讀性,類集成的碼結構會直白易懂些,而且然裝飾器合“開閉則”,但它會給程帶來更多類,動態(tài)飾在多層飾時會更雜。所以體上使用飾器模式時候也是害相較取輕,為了頻繁修改經(jīng)成型的類而引入多裝飾器。應用的候一定要記裝飾器“增強”個事物用,可千萬把事物本實現(xiàn)的主輯用裝飾實現(xiàn)了。文來自微公眾號:管叨 bi 叨 (ID:kevin_tech),作者:KevinYan11