一些常用的軟件設計原則

在架構設計過程中,瞭解一些先輩們總結出來的常用的設計原則非常有用,在實踐過程中,結合這些理論,相信架構水平會有質的提升,就像是一本武功祕籍,在學的過程中遵循它的rule,你的武功自然就上去了。我真的感覺這些原則非常有用:


1.Don't Repeat Yourself

在上一篇已經有闡述。

 

2.面向接口編程而不是面向實現的編程

接口是穩定的,也是抽象的,越抽象的東西越易於擴展,這個是鐵的事實。IOC近幾年爲什麼那麼盛行,當然有它的道理:在實際代碼中,只有接口,具體的實現有IOC容器去注入,我可以靈活地注入想要的任何實現,想換個實現也很容易,客戶端調用代碼根本不需要改動,這樣多好。面向接口編程解除了client代碼與實際實現類的耦合。

 

3.避免過度設計(You ain't gonna need it)

設計時,只考慮設計必須的功能,避免過度設計。只實現目前需要的功能,需要時你在添加。

WebSphere的設計者就表示過他過度設計了這個產品 。我們的程序員或是架構師在設計系統的時候,會考慮很多擴展性的東西,導致在架構與設計方面使用了大量折衷,最後導致項目失敗。這是個令人感到諷刺的教訓,因爲本來希望儘可能延長項目的生命週期,結果反而縮短了生命週期。

 

4.迪米特原則(最小知識原則)

這個原則在講Facade原則時,有提到,最小知識原則,顧名思義就是在設計過程中,避免給用戶複雜的調用和使用關係,給用戶呈現的東西越簡單越好,Facade模式通過迪米特原則,可以減少了客戶端代碼和底層實現類之間複雜的耦合關係,尤其在軟件系統與子系統之間存在複雜的交互關係時,迪米特原則顯得很重要。

 

例如:

final String outputDir = ctxt.getOptions().getScratchDir().getAbsolutePath();

這麼長的一串對其它對象的細節,以及細節的細節,細節的細節的細節……的調用,增加了耦合,使得代碼結構複雜、僵化,難以擴展和維護。

 

5.面向對象5大設計原則之-Single Responsibility Principle (SRP) – 職責單一原則

關於單一職責原則,其核心的思想是:一個類,只做一件事,並把這件事做好,其只有一個引起它變化的原因 。單一職責原則 可以看作是低耦合、高內聚在面向對象原則上的引申,將職責定義爲引起變化的原因,以提高內聚性來減少引起變化的原因。職責過多,可能引起它變化的原因就越 多,這將導致職責依賴,相互之間就產生影響,從而極大的損傷其內聚性和耦合度。單一職責,通常意味着單一的功能,因此不要爲一個模塊實現過多的功能點,以 保證實體只有一個引起它變化的原因。

 

6.面向對象5大設計原則之 -Open/Closed Principle (OCP) – 開閉原則

關於開發封閉原則,其核心的思想是:模塊是可擴展的,而不可修改的。也就是說,對擴展是開放的,而對修改是封閉的

對擴展開放,意味着有新的需求或變化時,可以對現有代碼進行擴展,以適應新的情況。
對修改封閉,意味着類一旦設計完成,就可以獨立完成其工作,而不要對類進行任何修改。

 

7.面向對象5大設計原則之 - 里氏替換原則

子類必須能夠替換成它們的基類。即:子類應該可以替換任何基類能夠出現的地方,並且經過替換以後,代碼還能正常工作。另外,不應該在代碼中出現 if/else之類對子類類型進行判斷的條件。里氏替換原則LSP是使代碼符合開閉原則的一個重要保證。正是由於子類型的可替換性才使得父類型的模塊在無 需修改的情況下就可以擴展。

 

8.面向對象5大設計原則之 - Interface Segregation Principle (ISP) – 接口隔離原則

接口隔離原則意思是把功能實現在接口中,而不是類中,使用多個專門的接口比使用單一的總接口要好。

舉個例子,我們對電腦有不同的使用方式,比如:寫作,通訊,看電影,打遊戲,上網,編程,計算,數據等,如果我們把這些功能都聲明在電腦的抽類裏 面,那麼,我們的上網本,PC機,服務器,筆記本的實現類都要實現所有的這些接口,這就顯得太複雜了。所以,我們可以把其這些功能接口隔離開來,比如:工 作學習接口,編程開發接口,上網娛樂接口,計算和數據服務接口,這樣,我們的不同功能的電腦就可以有所選擇地繼承這些接口。

這個原則可以提升我們“搭積木式”的軟件開發。對於設計來說,Java中的各種Event Listener和Adapter,對於軟件開發來說,不同的用戶權限有不同的功能,不同的版本有不同的功能,都是這個原則的應用。

 

9.面向對象5大設計原則之 - Dependency Inversion Principle (DIP) – 依賴倒置原則

高層模塊不應該依賴於低層模塊的實現,而是依賴於高層抽象。

舉個例子,牆面的開關不應該依賴於電燈的開關實現,而是應該依賴於一個抽象的開關的標準接口,這樣,當我們擴展程序的時候,我們的開關同樣可以控 制其它不同的燈,甚至不同的電器。也就是說,電燈和其它電器繼承並實現我們的標準開關接口,而我們的開關產商就可不需要關於其要控制什麼樣的設備,只需要 關心那個標準的開關標準。這就是依賴倒置原則。

這就好像瀏覽器並不依賴於後面的web服務器,其只依賴於HTTP協議。這個原則實在是太重要了,社會的分工化,標準化都是這個設計原則的體現。

 

10.共同封閉原則

一個包中所有的類應該對同一種類型的變化關閉。一個變化影響一個包,便影響了包中所有的類。一個更簡短的說法是:一起修改的類,應該組合在一起(同一個包 裏)。如果必須修改應用程序裏的代碼,我們希望所有的修改都發生在一個包裏(修改關閉),而不是遍佈在很多包裏。CCP原則就是把因爲某個同樣的原因而需 要修改的所有類組合進一個包裏。如果2個類從物理上或者從概念上聯繫得非常緊密,它們通常一起發生改變,那麼它們應該屬於同一個包。

CCP延伸了開閉原則(OCP)的“關閉”概念,當因爲某個原因需要修改時,把需要修改的範圍限制在一個最小範圍內的包裏。


11.共同重用原則

包的所有類被一起重用。如果你重用了其中的一個類,就重用全部。換個說法是,沒有被一起重用的類不應該被組合在一起。CRP原則幫助我們決定哪些類應該被 放到同一個包裏。依賴一個包就是依賴這個包所包含的一切。當一個包發生了改變,併發布新的版本,使用這個包的所有用戶都必須在新的包環境下驗證他們的工 作,即使被他們使用的部分沒有發生任何改變。因爲如果包中包含有未被使用的類,即使用戶不關心該類是否改變,但用戶還是不得不升級該包並對原來的功能加以 重新測試。

 

12.好萊塢原則
好萊塢原則就是一句話——“don’t call us, we’ll call you.”。意思是,好萊塢的經紀人們不希望你去聯繫他們,而是他們會在需要的時候來聯繫你。也就是說,所有的組件都是被動的,所有的組件初始化和調用都 由容器負責。組件處在一個容器當中,由容器負責管理。

簡單的來講,就是由容器控制程序之間的關係,而非傳統實現中,由程序代碼直接操控。這也就是所謂“控制反轉”的概念所在:

1.不創建對象,而是描述創建對象的方式。
2.在代碼中,對象與服務沒有直接聯繫,而是容器負責將這些聯繫在一起。

控制權由應用代碼中轉到了外部容器,控制權的轉移,是所謂反轉。

好萊塢原則就是IoC(Inversion of Control)或DI(Dependency Injection )的基礎原則。這個原則很像依賴倒置原則,依賴接口,而不是實例,但是這個原則要解決的是怎麼把這個實例傳入調用類中?你可能把其聲明成成員,你可以通過 構造函數,你可以通過函數參數。但是 IoC可以讓你通過配置文件,一個由Service Container 讀取的配置文件來產生實際配置的類。但是程序也有可能變得不易讀了,程序的性能也有可能還會下降。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章