歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

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

市面上的“設計模式“書籍文章,皆針對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