市面上的“設計模式“書籍文章,皆針對Java/C++/C#等面向對象語言,似乎離開了面向對象的種種特性,設計模式就無法實現,沒有用武之地了。
是這樣嗎?設計模式的概念是從建築領域引入的,本身從沒歧視過面向過程編程語言,它只是對一類問題的普遍解決方案而已。面向對象語言因為有類、多態等特點,使得開發者們容易達到:隱藏細節、封裝變化,而這與設計模式的目的比較一致,所以大師們愛把設計模式與面向對象語言二位一體的使用。然而,存在即合理,C語言直到今日仍然在大型軟件工程中擔綱主角,其種種設計方法其實與我們通常見到的設計模式本質是相同的。例如nginx這個純C語言寫就的的高性能WEB服務器,就有許多地方使用到了市面書籍提到的設計模式。下面通過nginx源碼來看看C語言是怎麼做的。當然,UML圖都是我根據代碼意圖所畫,並不准確(C語言真沒法畫UML),只用於方便理解,呵呵。
strategy模式:
該模式用於客戶代碼在“無知”狀態下,可以使用種種不同的實現。下面我們以nginx對網絡IO操作的封裝部分來看看C語言的實現吧。
設計模式就是通過封裝變化來解耦,所以,我們先要找出網絡IO操作的變化點來。nginx是跨平台的,它會支持linux、freebsd、solaris等操作系統,而每個操作系統的網絡IO操作是不同的,這就是變化點了。
所以,nginx首先定義了ngx_os_io_t來封裝這些變化。
[cpp]擁有函數指針的struct,我通常認為它們是OO中的abstract class,實現它們的文件(一堆函數)要對應到OO上,我則喜歡把它們當做子類來看。對於void*這樣的成員,要根據意圖來看了,通常我會轉換成聚合加繼承的關系。
ngx_io會在相應的ngx_os_specific_init方法中,來策略性的選擇到底使用哪個實現。客戶代碼只需要簡單的調用ngx_io中的方法即可。