大家知道,软件的正向工程,是从软件的需求获取开始,大概经历需求分析,概要分析,领域分析,设计分析,详细设计,代码实现,部署,实施这几个步骤,最终交付给用户使用。而在某些时候,比如某个软件产品是用PHP开发的,因为某些原因,我们想移植到JAVA平台去。或者某公司看到某个软件的市场前景很好,想COPY它的主要功能,然后经过加工润色后推出一个具有相同功能,更好用户体验或更多功能的软件。或者单纯的以研究软件的结构、设计思想为目的。基于这些需求,我们需要逆向工程。正向工程是一个从过程导出结果的步骤,而逆向工程是从结果推导出过程,逆向工程从代码出发,最后的成果往往是分析模型,从分析模型,我们可以得到产品的设计思想。
Django是python的一个Web开源框架。在生产环境下,它通过wsgi接口与apache的mod_wsgi通讯,完成代码解析,根据url请求,执行相应代码并将返回结果通过http协议传输结果呈现给用户。在开发环境下,我们常常使用Django自带的webserver进行开发与调试。由此Django无需任何其它组件(如apache)的支持,就可以形成一个完整的基于python的web解决方案。
在此,我将与大家粗略的探讨一下Django是如何工作的,而研究的方法就是上面所提到的逆向工程。废话就不多说了,让我们开始。
要想知道Django是如何工作的,首先得研究下Django提供的Webserver。因为它是Http请求的入口,Http响应的出口。它接收用户在浏览器输入的URL,然后经过一系列复杂的操作,变成了用户想要的内容,并将内容通过Http发送给用户。所以,Webserver将是我们研究Django的切入点。
Webserver
包与类的关系结构图
Webserver所需要的类和包大致如上图所示(某些配置相关的类没有在上图中表示出来),由于Python语言的特性,在上图中我们看到的以.py后缀结尾的是python文件,我们也可以把它当作是一个package。以.class后缀结尾的代表类。虽然Django框架不是用完全面向对象的思想来开发的,但完全可以用面向对象的思想去分析它。下表将展示包的描述。
包名
|
父级包
|
在WebServer中起到的作用
|
BaseHTTPserver.py
|
N/A
|
提供http请求处理类的包
|
contrib
|
django
|
提供Django框架的一般性部件
|
handlers.py
|
django.contrib
|
提供处理http请求类的包
|
staticfiles
|
django.contrib
|
提供处理http请求类的包
|
management
|
django.contrib.
staticfiles
|
提供管理“处理http请求对象”类的包
|
commands
|
django.contrib.
staticfiles.
management
|
提供管理“处理http请求对象”类的包
|
runserver.py
|
django.contrib.
staticfiles.
management.
commands
|
提供管理“处理http请求对象”类的包
|
core
|
django
|
提供Django框架的引擎
|
handlers
|
django.core
|
提供处理http请求核心类的包
|
base.py
|
django.core.
handlers
|
提供处理http请求核心类的包
|
wsgi.py
|
django.core.
handlers
|
提供处理http请求核心类的包
|
management
|
django.core
|
提供管理“
处理http请求对象
”核心类的包
|
__init__.py
|
django.core.
management
|
提供管理“
处理http请求对象
”核心类的包
|
base.py
|
django.core.
management
|
提供管理“
处理http请求对象
”核心类的包
|
commands
|
django.core.
management
|
提供管理“
处理http请求对象
”核心类的包
|
runserver.py
|
django.core.
management.
commands
|
提供管理“
处理http请求对象
”核心类的包
|
servers
|
django.core
|
提供实现服务器运行类的包
提供处理http请求类的包
|
basehttp.py
|
django.core.
servers
|
提供实现服务器运行类的包
提供处理http请求类的包
|
SocketServer.py
|
N/A
|
提供实现服务器运行类的底层包
提供处理http请求类的底层包
|
wsgiref
|
N/A
|
提供实现服务器运行类的底层包
提供处理http请求类的底层包
|
handlers.py
|
wsgiref
|
提供实现服务器运行类的底层包
提供处理http请求类的底层包
|
simple_server.py
|
wsgiref
|
提供实现服务器运行类的底层包
提供处理http请求类的底层包
|
看似包很多,但仔细观察,我们会发现,包聚集的无非是运行http服务器、管理http请求、处理http请求这三种类,只是所在的层次不一样,SocketServer.py包与BaseHTTPserver.py包提供最底层的实现,wsgiref包提供过渡层的实现,django包提供应用层的实现。
包示意图
从上图看来,可能会对包的结构有一个更加直观的了解。WebServer的运行是由management包来驱动调度的。management包启动server,并等待tcp连接过来,management包还会创建一个request handle的实例。当有一个连接过来时,这个request handle实例会调用handle实例(也就是staticfilehandle对象)进行相应的逻辑处理,如加载视图中间件,模板中间件等一系列的操作,并将处理结果写入socket,发送给浏览器。从包图上我们可以了解系统模块间的交互关系,如果要更加深入的理解细节,我们需要对包中的类进行分析。下表将展示类的描述。
类名
|
所属包
|
父级
|
在WebServer中起到的作用
|
BaseHTTPRequestHandler
|
BaseHTTPserver.py
|
StreamRequestHandler
|
request handle底层类
|
StaticFilesHandler
|
django.contrib
.
staticfiles.handlers.py
|
WSGIHandler
|
处理http请求的实体,用户逻辑处理,产生http响应结果,属于handle模块
|
Command
|
django.contrib.
staticfiles.
management
.
commands.runserver.py
|
RunserverCommand
|
调度类,取得handle实体对象等
|
BaseHandler
|
django.core
.
handlers.
base.py
|
N/A
|
handle基类
|
WSGIHandler
|
django.core
.
handlers.
wsgi.py
|
BaseHandler
|
handle类,负责django框架handle的核心逻辑。
|
BaseCommand
|
django.core.
management.
base.py
|
N/A
|
调度基类
|
Command as RunserverCommand
|
django.core.
management
.
commands.
runserver.py
|
BaseCommand
|
调度类,负责django框架调度的核心逻辑。
|
WSGIRequestHandler
|
django.core
.
servers.
basehttp.py
|
simple_server.
WSGIRequestHandler
|
request handle核心类
|
WSGIServer
|
django.core
.
servers.
basehttp.py
|
simple_server.
WSGIServer
|
建立http服务器
|
BaseRequestHandler
|
SocketServer.py
|
N/A
|
request handle底层类,调用handle模块获取http响应,写入socket
|
BaseServer
|
SocketServer.py
|
N/A
|
建立http服务器
|
StreamRequestHandler
|
SocketServer.py
|
BaseRequestHandler
|
request handle底层类
|
TCPServer
|
SocketServer.py
|
BaseServer
|
建立http服务器
|
BaseHandler
|
wsgiref.
handlers.py
|
N/A
|
request handle与handle模块之间的代理类,request handle通过该类调用handle对象
|
SimpleHandler
|
wsgiref.
handlers.py
|
wsgiref
.
handlers.py.
BaseHandler
|
request handle与handle模块之间的代理类,request handle通过该类调用handle对象
|
WSGIRequestHandler
|
wsgiref
.
simple_server.py
|
BaseHTTPRequestHandler
|
request handle底层类
|
WSGIServer
|
wsgiref
.
simple_server.py
|
HTTPServer
|
建立http服务器
|
HTTPServer
|
BaseHTTPserver.py
|
TCPServer
|
建立http服务器
|
ServerHandler
|
wsgiref
.
simple_server.py
|
SimpleHandler
|
request handle与handle模块之间的代理类,request handle通过该类调用handle对象
|
经过分析后,我们可以得出运行WebServer及处理Http请求所需的类静态图,通过类静态视图与分析调试,我们可以得出对象的时序图。我们可以将WebServer的监听及处理当作两个用例来处理,由此可以得出针对这两种不同用例的时序图,如下所示:
类的静态图
类的时序图
服务器运行时序图
处理请求时序图
至此,我们建立了Django框架中自带HttpServer的设计模型,有了设计模型,我们可以通过它反推出分析模型。如果我们以移植为目的(如需要做一个JAVA版的HttpServer),可以在得到分析模型后,再开始针对JAVA进行设计建模,然后进行代码编写。如果以优化裁剪为目的,我认为推导出设计模型已经足够了,可以开始思考如何精简类,如何裁剪项目。