歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 設計模式在C語言中的應用--讀Nginx源碼

設計模式在C語言中的應用--讀Nginx源碼

日期:2017/3/1 10:34:41   编辑:Linux編程

市面上的“設計模式“書籍文章,皆針對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]
  1. typedef struct {
  2. ngx_recv_pt recv;
  3. ngx_recv_chain_pt recv_chain;
  4. ngx_recv_pt udp_recv;
  5. ngx_send_pt send;
  6. ngx_send_chain_pt send_chain;
  7. ngx_uint_t flags;
  8. } ngx_os_io_t;
這裡有五個函數指針(*_pt都是函數指針)和一個變量,用於收發網絡數據,我把它理解為OO中的abstract class(每個ngx_os_io_t定義的變量都會重新實現這五個函數)。

擁有函數指針的struct,我通常認為它們是OO中的abstract class,實現它們的文件(一堆函數)要對應到OO上,我則喜歡把它們當做子類來看。對於void*這樣的成員,要根據意圖來看了,通常我會轉換成聚合加繼承的關系。


ngx_io會在相應的ngx_os_specific_init方法中,來策略性的選擇到底使用哪個實現。客戶代碼只需要簡單的調用ngx_io中的方法即可。

Copyright © Linux教程網 All Rights Reserved