马海波,李圣龙
改进HMVC设计模式应用于PHP开发的探索
马海波,李圣龙
讨论了以MVC设计模式为核心所构建的PHP开发框架的优缺点,介绍了HMVC设计模式的基本概念,阐述了在PHP开发框架中应用HMVC设计模式所能解决的问题及所带来的优势,提出并比较了应用HMVC设计模式对PHP框架进行改进的两种具体方式。
PHP;MVC;设计模式;HMVC
PHP是目前主流的编程语言,被广泛应用于Web开发领域,PHP 5实现了面向对象技术的全面支持,使适合Web项目开发的MVC设计思想得以在PHP中实现。目前,主流PHP开发框架广泛使用了MVC设计模式。然而随着Web系统规模的扩大,MVC模式的潜在缺点逐渐显现。HMVC是一种新型的设计模式,通过实现控制器之间的通讯,可以有效的对系统解耦,比MVC设计模式更加适用于大型Web项目及分布式项目的开发。
本文通过分析比较MVC和HMVC设计模式在PHP框架设计中的优缺点,提出了PHP中HMVC模式的两种实现方式,为Web应用程序开发人员在项目开发设计中选用不同的开发模式和软件结构来架构系统提供了参考。同时结合代码实例,介绍了基于HMVC思想设计的框架的原理及使用方式,为在实际项目中运用HMVC设计模式提供了借鉴的方法和技巧。
MVC是由Smalltalk-80引入的一种面向对象的设计模式,用于创建可重用的界面程序[1]。MVC模式将程序分为3个部分:控制器(Controller)、模型(Model)、视图(View)[2-4]。MVC模式在概念上的定义是很丰富的,但是为了维持模型的一般性,对于许多实现上的问题并没有给出明确的定义,不同的环境下可能有不同的实现方式[5]。在基于 MVC的PHP框架中,控制器、模型、视图的关系及调用的流程如图1所示:
图1 MVC结构图
(1)用户访问URL触发网络请求(Request)。
(2)根据网络请求参数,程序调用与之相对应的控制器与控制器中的方法。
(3)控制器中方法根据用户的请求及请求中的信息,载入所需模型和视图,并调用模型层方法。
(4)模型层根据控制器的调用请求,执行对应的业务逻辑,并返回结果给控制器。
(5)控制器调用视图层,将模型层返回的结果通过视图传递给用户。
由于控制器内同时载入了模型和视图,所以模型和视图之间也可以完成相互的调用。
MVC模式中,控制器负责处理程序的控制执行逻辑,模型负责处理具体业务逻辑及数据库交互操作,视图则主要负责程序与用户的交互。MVC设计模式将代码的功能职责细分,视图的分离使得美工和前端设计人员可以不必掌握后台编程技术,而后台编程人员也无需掌握美工和前端技术,这极大的提高了PHP这门语言的开发效率与实用性。目前,CodeIgniter等大型的商业框架,均基于这种架构设计而成。
然而,MVC也有一个非常大的缺点,即和整个软件发展思路相背离的,MVC在提高系统内聚的过程中,将导致系统耦合性的增加[6]如图2所示:
图2 MVC系统调用图
图2呈现了基于MVC设计模式的PHP系统模块间的关联。在本地系统(Local)中,User(用户模块,封装了所有用户相关的信息)和Login(登录模块,封装了所有登录相关信息)是两个独立的MVC模块,由外部请求驱动。由于User和Login模块的业务联系比较紧密,有可能出现重复逻辑,为了提高软件的复用性,MVC框架允许控制器调用不同模块的模型和视图。对于远程系统(Remote)来说,如果远程系统和本地系统采用相同的MVC架构,和本地系统一样,远程系统的控制器也可以引入本地系统的多个模型和视图(远程引用文件对系统的安全性有较大威胁);如果系统并非采用相同架构的框架开发,甚至开发语言都不尽相同,这种情况下,实现分布式通信,则需要通过模拟请求来实现。
MVC设计模式的提出本身是为了提高系统的内聚,然而,从图2可以看出,当系统过为复杂,Model和View的耦合性将变得非常强[7]。而当程序需要支持分布式部署时,针对不同类型的外部系统,实现通信需要兼顾多种方式,会使不同模块间的控制器、模型、视图调用关系变得更加复杂,这极大的降低了系统的可维护性。所以,MVC在处理中小型Web项目时,强内聚使得其具有相当大的优势,但是耦合性高的弊端使得其并不适合开发大型复杂的Web项目。
2.1 HMVC设计模式原理
Jason Cai[8]等(2000)提出HMVC是一种新型的设计模式,它提供了一种容易理解的软件组织架构,将MVC层次模块化,要求不同的程序逻辑之间保持清晰的界限,这种架构通过增加控制器之间的通信,降低了MVC模式中各模块组件间的耦合,提高了系统的复用性、可扩展性和可维护性如图3所示:
图3 HMVC原理图
图3给出了HMVC的原始结构。与MVC模式相比,HMVC架构需要遵循两点要求:一是每个MVC模块的控制器只能调用处理自身业务逻辑的模型和显示自身界面的视图;二是多个MVC模块之间的调用,必须通过控制器进行通信。
由于Web中控制器是通过浏览器URL请求调用的,所以HMVC的层次结构并不固定。当用户将调用A的请求发送给浏览器,A要使用B,B要使用C,那么A是顶层,B是第二层,C是第三层;而当用户发送调用B的请求给浏览器,如果B需要A和C模块的支持,这时B是顶层,而A和C则为第二层。
2.2 基于请求机制的HMVC架构
为解决基于MVC的PHP框架中的问题,提出了基于请求通信的新型HMVC模式的PHP框架结构如图4所示:
图4 基于请求的HMVC模式
在基于HMVC结构的PHP框架中,系统限制了不同模块间的调用,只允许各模块通过控制器进行通讯,而控制器间的通信,必须统一采用请求(request)的方式。
图4和图2的结构的对比如表1所示:
表1 HMVC与MVC的对比
首先,通过限制对非自身模型和视图的调用,基于请求机制的HMVC架构很好的解决了模块之间模型,视图间耦合性强的问题。同时,这种架构方式也带来了潜在的其它优秀特性。
(1)传统的MVC框架中,由于视图和模型存在耦合,为了解耦,视图和模型中也可能存在控制逻辑。而 HMVC通过控制器间的通信解决了视图和模型的耦合问题,将控制功能完全统一在了控制器内,这使得系统职责划分更加清晰,对系统各部分的优化更加容易,系统的可维护性和可扩展性能够得到大幅提升。所以这种架构能够应对更加复杂的Web项目开发。
(2)控制器的通讯统一采用请求机制,无论是对于内部还是外部系统,无论对于结构相同或不同的系统,都保持了通讯的一致性。HMVC强化了逻辑上的对应关系、统一了通信方式、增加模块间的协调性,这种结构更加适用于分布式项目的开发[9]。
(3)基于请求的通讯机制,避免了分布式系统间文件的相互调用,也提高了系统的安全性。
2.3 基于Ajax技术的实现方式
Ajax模拟请求,指一种创建交互式网页应用的网页开发技术,可以实现网页的异步更新。通过这种技术,可以在视图中向另外控制器发出模拟请求如图5所示:
图5 Ajax实现HMVC
这种方式需要控制器准备好请求参数,传递给视图,视图再将请求发送给其它控制器。
虽然请求的处理和请求的发送均由控制器来支配,符合HMVC设计模式的核心思想,但这种方式控制器不能直接向外发送请求,需要借助视图才能实现Ajax模拟请求,这种方式存在以下主要缺点。
(1)参数通过视图传递,类似于GET传值,降低了系统的安全性。
(2)程序需要借助Javascript技术进行实现,对程序员要求更高,不易使用。
(3)程序内部控制器之间的访问实际上通过是通过中间的视图层实现的,视图层并没有和控制器完全解耦,并非严格遵循HMVC设计思想。
2.4 基于封装请求类的实现方式
封装请求类是指将请求发送的方法和机制完全抽象封装到一个静态类中。控制器无需了解系统发送请求的原理,只需要向静态类中方法提供发送请求的命令和参数即可如图6所示:
图6 封装请求类实现HMVC
请求类中封装了模拟发送请求的方法集合。能够实现内部Post/Get请求的发送,外部Post/Get请求的发送等功能。同时,该类中包含对请求数据返回数据的统一处理,以保证内外部请求最终结果的一致性,方便程序调用操作。
下面给出了请求类中模拟内部 Post请求发送的实现方法,方法中省略了部分参数判断,验证及返回值处理工作,用于说明实现原理。
SendInnerPost()方法首先对当前控制器的环境进行保存,保存内部的POST和GET参数,然后根据方法的参数重新构建POST参数,并向其他控制器发送执行请求并保存请求结果。结束请求操作后,恢复环境,并返回请求结果。
在控制器内,当在登录(Login)控制器中执行$rsult=$this->_request->sendInnerPost('user','index','post' ,$arr);代码时,就会调用 User控制器中的 index方法,并将$arr数组以Post请求参数的形式发送过去。
内部模拟GET请求的方式与Post方式类似,均可采用基于调用文件方法的请求模拟。而向远程分布式系统模拟发送请求,则可以采用 PHP中内置的 curl扩展包实现,curl扩展包支持FTP、HTTP、HTTPS等各类协议,可以方便的实现PHP程序与各类分布式系统的通信。
封装请求类的方式,解决了Ajax技术实现HMVC中存在的问题,提高了HMVC框架的安全和复杂度,是一种更加适用于分布式和复杂系统开发的PHP框架解决方案。
本文采用面向对象的 MOOD度量方法来分析对比MVC与HMVC设计模式的耦合度。MOOD方法认为如果一个类调用另一个类的方法或变量,或者两个类之间存在消息传递,则这两类之间存在耦合关系[10]。
MOOD方法使用耦合因子CF来度量系统的耦合度。CF的值越大,则表示系统的耦合度值越高。在一个包含TC个类的系统中,其CF定义如下:
如果一个由x个模块组成的系统采用MVC或者HMVC设计模式,则该系统包含Controller类、Model类和View类各x个。
如图2所示,如果系统采用MVC设计模式,每个模块内的 Controller类与所有的 Model类和 View类耦合;而Model类只和本模块内的Controller类与View类耦合;View类只和本模块内的Controller类与Model类耦合。则耦合因子CFMVC计算如下:
如图3所示,如果系统采用HMVC设计模式,则各模块内的Controller类只与其他模块的Controller类以及该模块内的Model类和View类耦合;Model类和View类的耦合方式不变。则耦合因子CFHMVC计算如下:
两种设计模式的耦合因子对比如图7所示:
图7 耦合因子对比图
当系统内的模块数较大时(x≥20),采用HMVC设计模式可以明显地降低系统内的耦合度。因此,HMVC设计模式更适用于大型复杂系统的开发。
本文介绍了HMVC设计模式,提出了两种在PHP开发中改进HMVC设计模式的具体思路。通过分析对比和代码案例指出HMVC设计模式更为安全和便捷,并可以有效地降低系统内耦合度,更适用于开发大型复杂系统。
[1]Burbeck S. Applications Programming in Smalltalk-80: How to Use Model-View-Controller (MVC) [EB/OL]. http://st-www.cs.uiuc.edu/users/smarch/st-docs/mvc.html, 1992.
[2]李谱华.浅析 MVC设计模式及其应用[J].科技信息, 2010,16:652.
[3]孟勋.MVC与三层架构技术的应用研究[J].软件工程师, 2013,9:23-25.
[4]伍海波,匡静,朱承学.基于 MVC的教学资源管理系统的设计与实现[J].计算机技术与发展, 2014,7:214-218.
[5]陈乐, 杨小虎. MVC模式在分布式环境下的应用研究[J].计算机工程, 2006,19:62-64.
[6]涂刚,李建,刘华清等. ASP. NET MVC的研究[J].软件工程师, 2010,8:54-57.
[7]Gu Ming-xia, Tang Keming. Comparative analysis of Web Forms MVC and MVP architecture[J], Environmental Science and Information Application Technology (ESIAT), 2010,2:391-394.
[8]Cai J., Kapila R., PalG.. HMVC: The Layered Pattern for Developing Strong Client Tiers. www.javaworld.com, 2000
[9]耿立超.HMVC架构在富客户端的企业级开发中的应用[J].电脑编程技巧与维护, 2008,11: 15-17.
[10]ABREU F. B. e. The M00D metricsset[C]. //Proceedings of ECOOP’95 Workshop on Metrics. Aarhus, Denmark, 1995:150-152.
Exploration of HMVC Design Pattern Applied In PHP Developing
Ma Haibo, Li Shenglong
(Software Institute of Dalian Jiaotong University, Dalian 116052, China)
This paper discusses the merits and demerits of PHP Framework based on MVC design pattern. It introduces the basic concept of HMVC, elaborates the benefit and the problems which can be solved by using HMVC design pattern in PHP Framework. Then it puts forward these two methods of merging HMVC design pattern into PHP Framework and compares them.
PHP; MVC; Design Pattern; HMVC
TP311.5
A
2015.12.23)
1007-757X(2015)05-0026-04
马海波(1963-),男,大连交通大学,软件学院,副教授,硕士,研究方向:计算机网络体系结构、网络安全、软件结构,大连,116052李圣龙(1989-),男,大连交通大学,软件学院,硕士,研究方向:软件工程、Web前后端开发,大连,116052