大家知道,软件的正向工程,是从软件的需求获取开始,大概经历需求分析,概要分析,领域分析,设计分析,详细设计,代码实现,部署,实施这几个步骤,最终交付给用户使用。而在某些时候,比如某个软件产品是用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

         

        包与类的关系结构图

        

wKioL1PaT_yQkwcAAARzWZaW0XM617.jpg


        Webserver所需要的类和包大致如上图所示(某些配置相关的类没有在上图中表示出来),由于Python语言的特性,在上图中我们看到的以.py后缀结尾的是python文件,我们也可以把它当作是一个package。以.class后缀结尾的代表类。虽然Django框架不是用完全面向对象的思想来开发的,但完全可以用面向对象的思想去分析它。下表将展示包的描述。


包名父级包在WebServer中起到的作用
BaseHTTPserver.pyN/A提供http请求处理类的包
contribdjango提供Django框架的一般性部件
handlers.pydjango.contrib提供处理http请求类的包
staticfilesdjango.contrib提供处理http请求类的包
managementdjango.contrib.staticfiles提供管理“处理http请求对象”类的包
commandsdjango.contrib.staticfiles.management提供管理“处理http请求对象”类的包
runserver.pydjango.contrib.staticfiles.management.commands提供管理“处理http请求对象”类的包
coredjango提供Django框架的引擎
handlersdjango.core提供处理http请求核心类的包
base.pydjango.core.handlers提供处理http请求核心类的包
wsgi.pydjango.core.handlers提供处理http请求核心类的包
managementdjango.core提供管理“处理http请求对象”核心类的包
__init__.pydjango.core.management提供管理“处理http请求对象”核心类的包
base.pydjango.core.management提供管理“处理http请求对象”核心类的包
commandsdjango.core.management提供管理“处理http请求对象”核心类的包
runserver.pydjango.core.management.commands提供管理“处理http请求对象”核心类的包
serversdjango.core

提供实现服务器运行类的包

提供处理http请求类的包

basehttp.pydjango.core.servers

提供实现服务器运行类的包

提供处理http请求类的包

SocketServer.pyN/A提供实现服务器运行类的底层包
提供处理http请求类的底层包
wsgirefN/A提供实现服务器运行类的底层包
提供处理http请求类的底层包
handlers.pywsgiref提供实现服务器运行类的底层包
提供处理http请求类的底层包
simple_server.pywsgiref提供实现服务器运行类的底层包
提供处理http请求类的底层包


        看似包很多,但仔细观察,我们会发现,包聚集的无非是运行http服务器、管理http请求、处理http请求这三种类,只是所在的层次不一样,SocketServer.py包与BaseHTTPserver.py包提供最底层的实现,wsgiref包提供过渡层的实现,django包提供应用层的实现。


        包示意图

wKiom1PaRXHzXdQHAAJ9cEWgaYw589.jpg


        从上图看来,可能会对包的结构有一个更加直观的了解。WebServer的运行是由management包来驱动调度的。management包启动server,并等待tcp连接过来,management包还会创建一个request handle的实例。当有一个连接过来时,这个request handle实例会调用handle实例(也就是staticfilehandle对象)进行相应的逻辑处理,如加载视图中间件,模板中间件等一系列的操作,并将处理结果写入socket,发送给浏览器。从包图上我们可以了解系统模块间的交互关系,如果要更加深入的理解细节,我们需要对包中的类进行分析。下表将展示类的描述。



类名所属包父级在WebServer中起到的作用
BaseHTTPRequestHandlerBaseHTTPserver.pyStreamRequestHandlerrequest 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/Ahandle基类
WSGIHandler

django.core

.handlers.wsgi.py

BaseHandlerhandle类,负责django框架handle的核心逻辑。
BaseCommanddjango.core.management.base.pyN/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服务器
BaseRequestHandlerSocketServer.pyN/Arequest handle底层类,调用handle模块获取http响应,写入socket
BaseServerSocketServer.pyN/A建立http服务器
StreamRequestHandlerSocketServer.pyBaseRequestHandlerrequest handle底层类
TCPServerSocketServer.pyBaseServer建立http服务器
BaseHandlerwsgiref.handlers.pyN/Arequest handle与handle模块之间的代理类,request handle通过该类调用handle对象
SimpleHandlerwsgiref.handlers.py

wsgiref

.handlers.py.

BaseHandler

request handle与handle模块之间的代理类,request handle通过该类调用handle对象
WSGIRequestHandler

wsgiref

.simple_server.py

BaseHTTPRequestHandlerrequest handle底层类
WSGIServer

wsgiref

.simple_server.py

HTTPServer建立http服务器
HTTPServerBaseHTTPserver.pyTCPServer建立http服务器
ServerHandler

wsgiref

.simple_server.py

SimpleHandlerrequest handle与handle模块之间的代理类,request handle通过该类调用handle对象



        经过分析后,我们可以得出运行WebServer及处理Http请求所需的类静态图,通过类静态视图与分析调试,我们可以得出对象的时序图。我们可以将WebServer的监听及处理当作两个用例来处理,由此可以得出针对这两种不同用例的时序图,如下所示:

            

        类的静态图

wKioL1PaRu-wDfnqAAcbd7KnyAU283.jpg


        类的时序图

            服务器运行时序图

wKiom1PaRguDbq_MAAG_egDVqrg776.jpg


            处理请求时序图


wKiom1PaRirBpxN8AAGy3n2JXiQ585.jpg


      至此,我们建立了Django框架中自带HttpServer的设计模型,有了设计模型,我们可以通过它反推出分析模型。如果我们以移植为目的(如需要做一个JAVA版的HttpServer),可以在得到分析模型后,再开始针对JAVA进行设计建模,然后进行代码编写。如果以优化裁剪为目的,我认为推导出设计模型已经足够了,可以开始思考如何精简类,如何裁剪项目。