漫谈设计模式
什么是設計模式?(以前一直聽說,感覺很高大上)設計模式是對一系列OO設計中的經(jīng)驗進行復用。最終的目的是提高系統(tǒng)的復用、易維護、易擴展。軟件系統(tǒng)需求總是在不斷變化,面對的情況也會變化(不僅僅是因為產(chǎn)品狗……)。在軟件開發(fā)后,大量時間會進行維護。設計模式就是盡量設計能夠適應變化的系統(tǒng),使系統(tǒng)更有彈性,面對變化更能游刃有余。將設計模式的思想融合到自己的大腦,面對不同的需求應用對應的設計模式,就能設計出比較流弊(NB)的結(jié)構(gòu),提升代碼質(zhì)量。
接下來,我們就來聊聊各個設計模式吧。
一、策略模式(Strategy Pattern)
策略模式是什么京東?先看看定義:“定義算法族,分別封裝起來,讓他們之間可以相互替換,此模式讓算法的變化獨立于使用算法的客戶”。……嗯……還是不知道什么意思。大概翻譯一下:策略模式就是讓方法的實現(xiàn)獨立于方法的使用者,使得方法的變化不會影響使用者。打個比方:比如一個武士(使用者),具備一個“使用武器”的技能(方法),但是使用什么武器呢?這個武器可能是刀槍棍棒,不一定。那我們就把這個“使用武器”這個方法獨立于武士,把二者的實現(xiàn)分開。
定義大概就是那樣。我們來看看一個具體的應用場景。
場景:我們定義一個鴨子類,鴨子具有飛行的方法。但是有可能不同的鴨子飛的方法不一樣,有的像普通鴨子那樣飛,有的像飛機那樣飛(發(fā)揮一點想象力)。因此“飛”這個方法就是容易改變的。因此我們就將這個方法進行抽象,將其與鴨子的實現(xiàn)進行分離,盡量針對接口編程而非實現(xiàn)編程。所以將飛行方法用一個接口進行封裝,具體的不同的飛行類實現(xiàn)接口。然后采用組合的方式將飛行類包含到鴨子類中。這樣就使得方法和使用者獨立開來。
?
二、觀察者模式(Observer)
觀察者模式就比較容易明白了。先看看定義:“在對象之間定義一對多的依賴,這樣一來,當一個對象改變狀態(tài),依賴它的對象都會收到通知,并自動更新”。定義不難理解,但是什么情況下使用觀察者模式呢?應該也不難想到,比如當多個或者一個對象需要訪問同一個數(shù)據(jù)源,共享一個數(shù)據(jù)的時候(一對多),那就需要采用觀察者模式。同樣,我們具體用一個場景來分析。
場景:我們有一個氣象數(shù)據(jù)收集站(很不想用書上的這個例子……),會時不時的更新氣象站手機的數(shù)據(jù),如溫度啊,風向啊,污染指數(shù)啊,PM2.5之類的。現(xiàn)在我們開發(fā)三個APP,這三個APP都需要獲取氣象站的數(shù)據(jù),然后按照自己的業(yè)務邏輯處理獲得的數(shù)據(jù)。
那很明顯,上述就是一個一對多的例子,適合用觀察者模式。觀察者模式有一些固定的組件,先看圖。
可以看到,觀測著模式分為兩個部分:對象subject和gu觀察者Observer。對象就是我們需要共享的資源,觀察者就是要使用數(shù)據(jù)的客戶。作為一對多,要實現(xiàn)對象在更新的時候?qū)λ杏^測者的通知,因此對象那邊就需要對觀察者進行管理,知道有哪些觀察者,因此對象需要提供對觀察者的加入register、退出remove、群發(fā)消息notify的功能。這里我們用接口實現(xiàn)Subject。
對于觀察者,我們需要給對象提供更新數(shù)據(jù)的方法,這樣對象才知道以什么方式來通知觀察者數(shù)據(jù)。因此觀察者統(tǒng)一實現(xiàn)Observer接口。這樣,觀察者和對象就建立了聯(lián)系。
在java中,有對觀察者模式的實現(xiàn),在java.util.Observe*中實現(xiàn)。但是他的對象管理是用類實現(xiàn)的,WeatherDate是繼承父類。這樣就沒有定義為接口好。因為java不支持多繼承,如果WeatherData還想繼承其他類怎么辦,同時違背了“多組合,少繼承”的原則。
在jDK源碼中,很多都運用了觀察者模式,如Swing,RMI等等。
?
三、裝飾者模式(Decorator)
裝飾者模式也是比較明確的設計模式。首先看定義:“動態(tài)地將責任附加到對象上。想要擴展功能,裝飾著提供有別于繼承的另一種選擇”。簡單解釋一下,即當你想對某一種現(xiàn)有的東西進行擴展,但是又不能修改他的代碼,那就對他進行包裝,把你需要新加上去的功能“裝飾”上去。舉個栗子
場景:你在面館里點面(終于不用書上的例子了!),然后你就看菜單啊。菜單這樣寫著:經(jīng)典蘭州拉面(8¥),火腿(1¥),雞蛋(2¥),兩片羊肉(3¥)。我們現(xiàn)在要給這個餐廳做一個餐廳點菜管理系統(tǒng),需要對每次客人點的菜進行記錄,比如點的什么面啊,加了什么其他的沒啊。因為有的時候,有的人要面+雞蛋,有的人面+火腿,有的人面+雞蛋+火腿(太鋪張浪費了……)。很明顯,這個場景里面有一個不變的,或者說基本的,就是那碗面。而要變化的就是要不要加其他的東西。往面中加其他東西的過程就是在對那碗面?zhèn)€性化進行“裝飾”。(怎么感覺自己好啰嗦……)那我們怎么應用裝飾者模式來設計這個場景呢
在裝飾者模式中,由兩個部分組成。一個叫組件(被裝飾者),一個叫裝飾者。二者都是繼承至同一個父類。這里用到繼承,不是為了需要繼承行為,而是需要繼承同一種模式,使得組件和裝飾者能夠進行結(jié)合(因為都屬于一類)。在此應用場景中,蘭州拉面本身為需要被裝飾的組件,而加的蛋和腸作為裝飾者。
當需要進行使用時,將二者進行結(jié)合?經(jīng)典蘭州拉面 拉面 = new 火腿腸(經(jīng)典蘭州拉面)。這樣就等于新建了一個加了腸的蘭州拉面,通過調(diào)用cost可以計算加了腸的蘭州拉面多少錢。可以像上面一樣通過不同的包裝進行有選擇的擴展經(jīng)典蘭州拉面。這樣就避免了使用繼承。 在java.io中就使用了大量的裝飾者模式。裝飾者模式,就是體現(xiàn)了我們設計的一個重要原則,即開閉原則:對擴展開放,對修改閉合。 但是對于裝飾者模式,存在的問題就是如果存在依賴于組件本身的類型(因為加了裝飾者就會改變本身的類型),那就不好操作了。四、工廠模式?
工廠模式應該說是用的比較多的一種設計模式。在工廠模式中,分為兩類,一種是工廠方法模式,一種是抽象工廠模式。二者還是有一定的區(qū)別。
我們首先看看工程方法模式(Factory Method Pattern)。定義:“定義了一個創(chuàng)建對象的接口,但由子類決定要實例化的類是哪一個。工廠方法讓類把實例化推遲到子類”。好像不是很直觀。沒關系,老規(guī)矩,以實例分析,看類圖。
場景:有面館生產(chǎn)面。有做方便面的,有做拉面的。都是首先訂外賣的訂一種面, 然后對應的面館就做面。
工廠方法的特點就是首先通過抽象類的編寫,固定了不同面館面的模式。通過繼承基類,在子類中具體實例化自己的業(yè)務邏輯。
?
轉(zhuǎn)載于:https://www.cnblogs.com/ren-jie/p/5453078.html
總結(jié)
- 上一篇: 关于Element学习笔记
- 下一篇: Cisco IPSec *** Gre