`
russelltao
  • 浏览: 157779 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

设计模式在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来封装这些变化。

typedef struct {
    ngx_recv_pt        recv;
    ngx_recv_chain_pt  recv_chain;
    ngx_recv_pt        udp_recv;
    ngx_send_pt        send;
    ngx_send_chain_pt  send_chain;
    ngx_uint_t         flags;
} 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中的方法即可。


adapter模式:

这个模式用以适配接口,通常都是我们已经定义好一种接口了,有一个新的实现却有着不同的接口,接下来adapter就开始发力了。下面我们仍然以nginx对网络IO操作的封装部分来看。

linux平台下可能存在普通的IO或者异步IO方式。我们在最初已经封装好ngx_os_io_t接口了,客户代码都是这么直接使用的。现在linux实现了异步IO,而它的调用方式与普通的读写IO接口完全不同,所以,如果要支持aoi就需要一层adapter来适配ngx_os_io_t,这就是adapter方式了。


上图中,ngx_os_aio适配了原生的异步IO接口,这样,用户代码仍然像以前一样,只要直接使用ngx_io中的五个接口方法,当nginx的IO部分支持linux aio后,用户代码不需要修改。


bridge桥模式:

桥模式用于将抽象和实现分离,各自都能独立的变化。下面以nginx的核心概念module举例,虽然有些牵强,因为nginx的代码从来没这么用过:通常都是一个抽象module context只对应着一个实现module来用,但是,毕竟这种结构下还是可以达到抽象与实现分离的目的,桥模式只好对应到这上面了。

nginx是以module的概念贯穿始终的。它有一个基本的抽象层ngx_core_module_t(从意图上判断,context有抽象接口的功能,虽然简单从语法上看不出)。然后,nginx module有三个基本类型,分别是event(处理各种事件模型,如epoll/select等),http(处理各种http协议的事件),mail(处理mail相关的事件)。针对每种类型的module,都有许多个实现,比如event module就有9个实现,这里的每个实现其实也是个子类。


但是,在我们理解桥模式时,这些子类暂时要被看成是event module的实例。代码中看,像ngx_epoll_module这样的子类中,还是把一些通用的细节隐藏给ngx_event_core_module来做(管理这个词更合适)了。从这个角度可以认为,通过context接口,把三个基本module实现分开了。来看看类图:


nginx自己用时,是以ngx_module_t中的type成员来决定使用哪个实现的。目前的nginx代码中,如果用了一种接口就一定会指定相应的type。可是实际上,这也可以用来展示桥模式。以事件module为例来看看:


由于UML本就是针对OO语言的,所以以上我画的类图都比较牵强,什么是继承?什么是聚合?在C语言中,往往都是通过几个函数指针,或者void*指针实现各种封装和多态。没有什么语法上的关联,我就只能从代码意图中来判断了。而代码意图这个比较虚,因为不同的角度理解出来都不一样,所以这个确实不好画。太灵活了点,我只能从一个便于说明的角度来看,例如:上面的ngx_devpoll_module其实就是一个ngx_module_t,呵呵,但是,实际上它最关心的是ngx_event_actions_t的实现,如果完全根据语法来看,根本说不通的。但从代码意图中看,这些module并不关心ngx_module_t,所以我认为,它们只是在实现ngx_event_module_t了。

当然以上只是一家之言,不必当真,如果对nginx源码有研究的话,欢迎各位拍砖。


客观的说,C语言确实在封装上很差,就像nginx,如果我们要开发一个处理http协议的module嵌入进nginx进程,必须了解ngx_http_module里到底做了什么,真没隐藏啥细节,module开发者们表示很郁闷。上面的这些设计模式,只是做到了代码上的解藕。如果nginx用C++写的话,我相信,现在第三方module都能数以万计了。


分享到:
评论

相关推荐

    nginx源码分析-高性能服务器编写

    编写模块时需要注意遵循Nginx的编码标准和设计模式,以确保兼容性和稳定性。 ##### 基于Nginx的高性能服务器开发 利用Nginx强大的基础架构,可以进一步开发出更复杂的Web应用服务器。例如,通过添加自定义模块实现...

    Nginx模块源码 mod_strip

    1. **模块配置**:首先,`mod_strip`会在Nginx配置文件中通过指令被启用,例如: ``` http { ... strip /path/to/mod_strip.so; ... } ``` 这里的`strip`就是`mod_strip`模块的配置指令,用于加载模块的动态...

    网络考试系统源码(php)

    源码中的PHP文件通常会遵循MVC(Model-View-Controller)设计模式,Model层负责与数据库交互,获取或更新数据;View层负责展示用户界面;Controller层处理用户请求,协调Model和View。通过这种方式,代码结构清晰,...

    PHP实例开发源码-PHPCrazy 建站程序.zip

    5. **MVC模式**:PHPCrazy可能采用了Model-View-Controller(MVC)设计模式,将业务逻辑、数据和用户界面分离,提高代码可读性和可维护性。理解模型、视图和控制器各自的职责是深入学习的关键。 6. **模板引擎**:...

    基于PHP的LOGA5X建站系统utf-8源码.zip

    源码中可能包含配置文件、数据库连接脚本、模板文件、控制器类、模型类、视图文件等。理解这些文件的结构和作用,对于定制和优化LOGA5X系统至关重要。 五、部署与优化 部署LOGA5X系统通常需要配置合适的服务器环境...

    javaC语言试题生成与考试系统源码.rar

    5. **MVC(Model-View-Controller)架构**:这是一种常见的软件设计模式,用于分离业务逻辑、视图展示和用户交互。源码中会体现模型、视图和控制器之间的通信方式。 6. **试题生成算法**:系统的核心功能之一是自动...

    基于PHP的BlogMethodsBasic(基础版)JSPWeb安装包源码.zip

    6. MVC(Model-View-Controller)架构:为了实现良好的代码组织和分离关注点,Web应用往往采用MVC设计模式。Model负责数据处理,View负责展示,Controller处理用户请求并协调Model和View。在PHP和JSP项目中,这种...

    php商城完整版毕业设计源码

    根据提供的文件信息,“php商城完整版毕业设计源码”这一标题和描述,我们可以总结出以下相关的知识点: ### 1. PHP语言概述 - **定义**:PHP(Hypertext Preprocessor,即“超文本预处理器”)是一种通用开源脚本...

    php建设源码

    - Model-View-Controller(MVC)是一种常见的软件设计模式,常用于Web开发。 - Model处理业务逻辑和数据,View负责显示,Controller协调两者。 - PHP框架如Laravel、Symfony、CodeIgniter等都支持MVC模式,简化...

    基于PHP的appRainphp内容管理系统源码.zip

    通过研究源码,开发者可以了解appRain的工作原理,学习其设计模式和最佳实践,也可以根据需求进行定制和二次开发。 6. 开发与部署:使用appRain开发项目时,需要熟悉PHP开发环境的搭建,如安装PHP、配置Web服务器...

    基于PHP的FexBookBeta源码.zip

    3. **MVC模式**:大多数PHP框架采用Model-View-Controller(MVC)设计模式,将业务逻辑、数据和用户界面分离,有利于代码的组织和维护。 4. **数据库交互**:FexBookBeta可能会使用MySQL或PDO(PHP Data Objects)...

    PHP项目开发案例全程实录源码

    4. **MVC模式**:Model-View-Controller模式是Web开发中常用的设计模式,它将业务逻辑、数据和用户界面分离,使得代码结构清晰,易于维护。理解MVC架构对于大型项目尤为重要。 5. **框架应用**:PHP有许多流行的...

    基于PHP的站长目录源码.zip

    通常包括 MVC(Model-View-Controller)设计模式,将业务逻辑、视图呈现和数据处理分离开来,便于代码管理和扩展。 8. **版本控制**:源码可能使用Git或其他版本控制系统进行版本管理,这对于团队协作和代码历史...

    PHP实例开发源码—ShopEx php网上商店系统安装包.zip

    ...PHP(Hypertext Preprocessor)是一种广泛使用的开源脚本语言,尤其适合于Web开发,可以...通过对源码的研读和实践,开发者可以提升自己的技能,理解到如何在实际项目中应用PHP技术,构建高效、安全的网上商店系统。

    若干vc代码1352.rar

    2012-06-13 12:53 656,958 nginx源码剖析.pdf 2012-06-13 12:52 720,948 STM32中断.RAR 2012-06-13 13:30 1,124,527 图像模式识别--VC++技术实现.zip 2012-06-13 13:07 2,173,078 14123166.bmp 2012-06-13 13:47 2,...

    基于PHP的鱼知凡考试管理系统源码.zip

    基于PHP的鱼知凡考试管理系统可能采用了MVC(Model-View-Controller)设计模式。MVC将应用程序分为三个主要部分:模型(Model)负责数据处理和业务逻辑,视图(View)负责显示数据,控制器(Controller)协调模型和...

    PHP实例开发源码—PHPSay World 微社区系统(已包括手机版).zip

    PHPSay World 微社区系统很可能采用了MVC(Model-View-Controller)设计模式。这种模式将应用程序的数据模型、用户界面和业务逻辑分离,使得代码更易维护和扩展。 4. 数据库管理: 社区系统通常会使用数据库来...

    fastdfs-attn.zip

    在互联网应用中,它常用于存储图片、文档等大文件,尤其适合高并发访问和大量文件存储的场景。本文将围绕FastDFS的原理、部署和配置进行深入探讨。 一、FastDFS简介 FastDFS由C语言编写,其设计目标是简化分布式...

    基于PHP的74cms骑士人才招聘系统SE版源码.zip

    获取到"基于PHP的74cms骑士人才招聘系统SE版源码.zip"后,开发者可以通过阅读源码了解系统的实现原理,学习PHP的MVC(Model-View-Controller)设计模式,以及如何组织和优化PHP代码。此外,也可以根据业务需求进行二...

    PHP实例开发源码—社交系统 Jcow Lite中文版.zip

    其基于MVC(Model-View-Controller)设计模式,这种模式将业务逻辑、数据和界面显示分离,使代码更易于维护和扩展。 在【使用须知.txt】中,通常会包含安装步骤、系统需求、配置指南以及可能遇到的问题解决方案。这...

Global site tag (gtag.js) - Google Analytics