設(shè)計模式——面向?qū)ο笤O(shè)計原則

1.什么是面向?qū)ο笤O(shè)計
世界是具體的,認(rèn)知是抽象的。像自然界中的生物、植物、動物一個個名詞,就是對一系列具體個體抽象出來的稱謂,而魚、老虎、樹等就是一個個實在的具體。哦,也許你會說,樹也是對一系列具體個體的抽象出來的稱謂,對也不對,對是因為樹確實是一系列具體個體的抽象稱謂,不對是因為照這個邏輯下去,就會陷入死循環(huán),直到小到細(xì)胞,原子,夸克,但是你能保證夸克就是最小的具體嗎?還好前人已經(jīng)幫我們解決這個思考了,通過繼承的關(guān)系,可以從抽象開始,逐層的繼承下去,就會形成一個具有抽象與具體關(guān)系的層次關(guān)系,就如同我們的世界那樣,也是通過抽象與具體形成的層次。
面向?qū)ο蟮脑O(shè)計實質(zhì)是通過對現(xiàn)實世界提煉出符合需求的抽象封裝,然后通過逐層繼承抽象并拓展實現(xiàn),實現(xiàn)同一繼承來源然而變現(xiàn)多態(tài)性質(zhì)。
比如下圖的繼承關(guān)系,這是游戲的從最抽象出的對象,到角色、靜態(tài)采集物、場景,再到人物、寵物、怪、坐騎等,就是典型的面向?qū)ο笤O(shè)計。

2.為什么需要面向?qū)ο笤O(shè)計
軟件設(shè)計就難的是應(yīng)對變化、變化、變化。通過把系統(tǒng)功能封裝成一個個對象,就可以粒度細(xì)化、功能實現(xiàn)的耦合度低和職責(zé)獨立,細(xì)化了就能夠更好的把控;耦合度低就是高內(nèi)聚、松耦合,能夠減少功能實現(xiàn)之間的關(guān)聯(lián),降低修改的影響;職責(zé)單一獨立就能夠提高代碼復(fù)用,復(fù)用就能夠提高開發(fā)效率與提高可維護性。
為了能夠更好的實現(xiàn)面向?qū)ο笤O(shè)計,應(yīng)該做到隔離變化,也就是把變與不變隔離開,不要讓變化的東西影響到不變的,適應(yīng)軟件的變化。對象各有獨自的功能,也就是對象的功能要單一,新能功能類型不應(yīng)該影響到舊的對象。這里說的比較簡單,其實大師們已經(jīng)總結(jié)出面向?qū)ο笤O(shè)計原則來指導(dǎo)我們的開發(fā)了。
3.面向?qū)ο笤O(shè)計原則
3.1依賴倒置原則
- 高層模塊(穩(wěn)定)不應(yīng)該依賴于低層模塊(變化),二者都應(yīng)該依賴于抽象(穩(wěn)定) 。
- 抽象(穩(wěn)定)不應(yīng)該依賴于實現(xiàn)細(xì)節(jié)(變化) ,實現(xiàn)細(xì)節(jié)應(yīng)該依賴于抽象(穩(wěn)定)。
3.2開閉原則
- 對擴展開放,對更改封閉。
- 類模塊應(yīng)該是可擴展的,但是不可修改。
3.3單一職責(zé)原則
- 一個類應(yīng)該僅有一個引起它變化的原因。
- 變化的方向隱含著類的責(zé)任。
3.4里氏替換原則
- 子類必須能夠替換它們的基類(IS-A)。
- 繼承表達類型抽象。
3.5接口隔離原則
- 不應(yīng)強迫客戶程序依賴它們不用的方法。
- 接口應(yīng)該小而完備。
3.6優(yōu)先使用對象組合,而不是類繼承
- 類繼承通常為白箱復(fù)用,對象組合通常為黑箱復(fù)用。
- 繼承在某種程度上破壞了封裝性,子類父類耦合度高。
- 對象組合則只要求被組合的對象具有良好定義的接口,耦合度低。
3.7找出變化點,封裝變化點
- 尋找出變與不變的分割點,對二者封裝,讓設(shè)計者對單方面修改時不會影響到另一面。實現(xiàn)層次間的松耦合。
3.8面向接口編程,而不是面向?qū)ο缶幊?/h4>
- 不將變量類型聲明為某個特定的具體類,而是聲明為某個接口。
- 客戶程序無需獲知對象的具體類型,只需要知道對象所具有的接口。
- 減少系統(tǒng)中各部分的依賴關(guān)系,從而實現(xiàn)高內(nèi)聚、松耦合的類型設(shè)計方案。
4.面向接口設(shè)計
在現(xiàn)實中,面向接口設(shè)計隨處可見,比如那么多的標(biāo)準(zhǔn)協(xié)會,比如發(fā)布的C++標(biāo)準(zhǔn),C-98/03/11等,比如各個工廠生產(chǎn)的零件等,都有各自對應(yīng)的生產(chǎn)標(biāo)準(zhǔn),只有接口標(biāo)準(zhǔn)化,才會使產(chǎn)業(yè)更加強盛。相反,接口沒有標(biāo)準(zhǔn),就會造成生產(chǎn)力低下,根本無經(jīng)濟全球化一說了。
面向接口編程就是抽象需求成一個個獨立的接口/抽象類,然后被繼承或委托/組成的形式來實現(xiàn)或拓展新的具體或更加強大完善的抽象,通過層層封裝、繼承,最后就會實現(xiàn)運行時多態(tài)的特性,從而提高代碼的靈活性。
6.小結(jié)
本文通過分析什么是面向?qū)ο?,為什么需要面向?qū)ο?,和面向?qū)ο笤O(shè)計的原則來說明軟件開發(fā)中面向?qū)ο笤O(shè)計是實現(xiàn)大型軟件程序的基石。面向接口編程,而不是面向?qū)ο缶幊?,能夠使代碼更加靈活,更加優(yōu)美強大。