MVC架构在Web应用系统的应用

时间:2011-08-28

 

  和C/S结构相比,B/S结构受限于网络带宽不利于进行大数据量的统计分析,网络传输存在潜在的安全问题,还有用户界面不及C/S结构友好等等,但随着网络带宽和网络应用的发展,加上AJAX技术的流行,使得现在越来越多的MIS系统或基于MIS系统的化应用系统都开始倾向于采用B/S结构进行设计,充分利用B/S结构的优点。但是,要充分发挥Web应用的内在潜力,挖掘应用深度和扩大适应能力,需要采用先进的应用架构和以实用为根本准则,使得系统既能满足业务需求,又能适应将来发展需要。因此,在开发Web应用系统时需要尽量遵循Web应用系统设计原则。

  1  MVC描述的软件模型

  MVC是三个单词的缩写,分别为: 模型(Model),视图(View)和控制Controller)。 MVC模式的目的就是实现Web系统的职能分工。 Model层实现系统中的业务逻辑,通常可以用JavaBean或EJB来实现。 View层用于与用户的交互,通常用JSP来实现。 Controller层是Model与View之间沟通的桥梁,它可以分派用户的请求并选择恰当的视图以用于显示,同时它也可以解释用户的输入并将它们映射为模型层可执行的操作。这三层结构之间的关系如图1所示。

  模型层(也称业务层)用于处理程序逻辑。它的任务是管理应用程序域的行为和数据,响应来自控制层的状态指令,把原有数据按照业务逻辑转换成指定意义的数据提供给视图层显示。

  视图层用于把表示模型数据、逻辑关系和状态的信息以特定的形式表现在用户界面上。视图层的显示信息来自模型层,同一个模型可以对应多个视图。

  控制层用于处理用户与软件的交互操作。控制层通知模型和视图做出相应的状态改变,使模型和视图协调工作。

  2  MVC模式设计

  模型表示企业数据和业务规则。在MVC的三个部件中,模型拥有多的处理任务。例如它可能用象EJBs和ColdFusion Components这样的构件对象来处理数据库。被模型返回的数据是中立的,就是说模型与数据格式无关,这样一个模型能为多个视图提供数据。由于应用于模型的代码只需写就可以被多个视图重用,所以减少了代码的重复性。MVC模式把界面表现和逻辑控制语句强制分离,解决了页面设计和程序开发中的工作交错与冲突,并解决了由于商业逻辑嵌入造成程序不可重用而且很难维护的问题。

  本文设计了一个基于PHP语言、XML和XSL模板技术的MVC架构的Web应用系统。

  2.1 代码结构

  在系统中每一个页面被定义为一个Action,控制器中定义了每一个Action对应的模型和视图,它们之间的对应关系如图2所示。

  表1为系统的基础代码结构,除少量的静态页面放在htdocs目录下外,其余的程序都放在PHP的库文件目录下。

  在这个代码结构中,模型、视图和控制器三部分分别放置在不同目录中。其中,视图层包括显示模板(XSL)和页面操作控制(JS)二部分,模型层包括业务逻辑处理类库(Action Class)、数据输出处理(Action Execute)和PHP基础类库(PHP Class)三部分。因此,在系统中各部分的开发由不同的角色来完成,角色之间的工作交错和冲突可以减少,使系统程序升级和维护的思路也更加明晰。

  2.2 系统实现

  在系统中,客户端浏览器中呈现的是系统的视图部分,而模型和控制器则是透明的。当Web 服务器接收到客户提交的HTTP请求后,交给服务器中的控制器来处理。控制器按照请求中的Action信息,从系统配置中提取此Action的映射表,并把此请求映射到相应的处理模型;处理模型进行业务逻辑处理,处理完后返回状态更新的请求并将XML格式的数据结果给控制器;控制器根据结果选择相应视图模板并合成视图返回给客户。程序架构如图3所示。

  2.2.1 控制层的实现

  在这个系统中,控制器主要有以下四个作用。

  (1)根据Action名称从数据库的映射表中找到处理此Action的模型信息、视图模板和此视图的用户操作控制信息。

  (2)调用模型处理Action请求。

  (3)合成业务逻辑处理返回的XML格式的数据信息和XSL视图模板为HTML的文件,并返回给客户端。

  (4)在接收到一个业务逻辑处理模型返回的状态更新请求后,调用一个新的业务逻辑处理模型处理此请求。

  控制器主要包括二个文件:includes/prepend.inc和includes/controller/controller.inc.prepend.inc文件被设定为自动增加在被访问的文件前,因此这个文件非常适合作为控制器的主文件;Controller.inc中主要是控制器中的处理函数。这二个文件的代码如下。

  prepend.inc

  <?

  include_once(″/action/configure/db.conf″);//数据库连接对象

  include_once(″/control/controller.inc″);//控制器

  …

  $actionobj=getaction($action);     //获得Action信息

  if($actionobj[″model″] !=″″){

  //调用model处理action请求信息

  include_once($actionobj[″model″]);

  eval(″\$modelobj=execute_″。$actionobj[″action″].″( );″);

  if($modelobj[″type″]==″xmldata″){//返回html

  //输出xml和xsl合成的html数据

  echo xmlpraser($modelobj[″data″],$actionobj[″view″]);

  }else if($modelobj[″type″]==″state″){  //请求更新状态

  header(″Location:?″。$modelobj[″data″]); //交新模型处理

  exit;

  }

  }else{//直接调用View输出}

  ?>

  controller.inc:

  <?

  ****得actionobj的信息****

  function getaction($action){

  global $dbobj,$conn,$result_id;      //数据对象,连接,结果集

  //从数据库中检索action对象信息

  $sqlstr=″select*from t_action where action=′″。$action.″′″;

  $result_id=$dbobj->exec($conn,$sqlstr);

  if($dbobj->fetch_row($result_id)){

  $actobj[″action″]=$action;

  //action的处理模型名称

  $actobj[″model″]=$dbobj->result($result_id,″model″);

  //action的视图模板信息

  $actobj[″view″]=$dbobj->result($result_id,″template″);

  //其他控制参数

  }else{ … }

  return $actobj;

  }

  //****解析xml和xslt****

  function php_scheme_get_all($Processor,$Schema,$RestUri){

  $url=$Schema .′:′。 $RestUri;

  return file_get_contents($url);

  }

  function xmlpraser($data,$xslpath){

  global $SYS_INCLUDEPATH;

  $parser=xslt_create( );  //初始化解析对象

  xslt_set_scheme_handlers($parser,array(′get_all′=>

  ′php_sheme_get_all′));      //设置处理方式

  $parms[″_xml″]=″<?xml version=\″1.0\″ encoding=\″gb2312\

  ″?>″ . $data;             //合成xml格式数据

  $parms[″_xsl″]=file_get_contents($SYS_INCLUDEPATH.

  ″\\″ . $xslpath);         //读取xsl模板文件

  $result.=xslt_process($parser,′arg:/_xml′,′arg:/_xsl′,

  NULL,$parms);        //合成视图

  xslt_free($parser);    //释放解析对象

  return $result;

  }

  ?>

  2.2.2 模型层的实现

  模型是系统的数据。此系统中模型层主要包括三部分内容。

  (1)业务逻辑处理。业务逻辑处理又可以分为二类:一类是抽象出来的业务逻辑,被封装成一个个PHP类;另一类是对某一具体Action的逻辑处理。

  (2)PHP的基础类库。此部分与业务逻辑无关,描述的是对任何一类的应用系统中都要使用的公共函数类,这些类可以被其他程序调用。

  (3)数据输出处理,把PHP数据转换成XML格式输出。

  按照控制器的定义,每一个Actionname都要调用一个命名为execute_actionname( )的函数,这个函数会返回Action的处理结果。处理结果有二种情况:一种是返回XML格式的数据;一种是返回要求系统更新状态的状态值。一个典型的模型处理器程序结构如下:

  <include_once(″/action/tool/tools.inc″);  //工具系统的基础类

  function gettoollist($toolid){       //获得工具信息

  //指定要获得的工具信息

  $params=array(″toolname″,″part_no″,″quantity″);

  $toolobj=new toolinfo;         //创建toolinfo类实例

  $toolstinfo=$toolobj->GetToolListinfo($toolid,$params);

  return $toolsinfo;           //返回工具列表信息

  }

  function getxml($toolsinfo){      //转换工具信息为xml格式

  while(list($id,$toolarray)=each($toolsinfo[″data″])){

  $xmlstr.=″<items>″;

  while(list($key,$value)=each($toolarray)){

  $xmlstr.=″<″ .$key. ″>″。$value.″</″。$key.″>″;

  }

  $xmlstr.=″</items>″;

  }

  return $xmlstr;

  }

  function execute_tool_toollist( ) {    //工具列表action的处理函数

  $toolinfo=gettoollist($toolid);      //工具信息

  if($toolinfo[″state″]){          //输出xml格式数据

  $rtnobj[″type″]=″xmldata″;

  $rtnobj[″data″]=getxml(($toolinfo);

  }else{                //跳转到错误处理页面

  $rtnobj[″type″]=″state″;

  $rtnobj[″data″]=″errorhandle″;

  }

  return $rtnobj;

  }

  ?>

  2.2.3 视图层的实现

  视图是一个虚拟表,其内容由查询定义。同真实的表一样,视图包含一系列带有名称的列和行数据。但是,视图并不在数据库中以存储的数据值集形式存在。行和列数据来自由定义视图的查询所引用的表,并且在引用视图时动态生成。对其中所引用的基础表来说,视图的作用类似于筛选。定义视图的筛选可以来自当前或其它数据库的一个或多个表,或者其它视图。分布式查询也可用于定义使用多个异类源数据的视图。此系统即使用了XSL模板技术。系统中的视图层包括二部分:一部分是放在/includes/template目录下的XSL模板;另一部分是放在/htdocs目录下的js和css文件。,由控制器来完成合成视图的任务。

  2.3 系统适应性

  从整个系统的设计结构可以看出,系统的业务逻辑和显示是分离的:首先由网页设计人员和程序员共同确定需要的数据项和Action名称,在控制器中添加此Action;之后,网页设计人员设计各个显示模板;程序人员完成相应的模型处理程序。这样的设计方法有利于对系统的维护和功能扩展。

  在MVC系统中处理用户需求的思路非常明确。视图的修改和模型处理的修改基本上是独立的,无论是在系统开发时期还是在系统维护时期,网页设计人员和程序员都可以更加专注于自己的任务。系统中的模型可以是自包含的,由于与控制器和视图相分离,所以很容易改变程序的数据层和业务规则。例如把数据库从Mysql移植到Oracle上只需改变数据库连接模型即可;而把界面显示从HTML改为Flash或WAP只需改变视图显示和相应控制器即可。一旦正确地实现了模型,视图将会正确地加以显示。这样,系统维护的成本和项目的开发风险都被大大降低。

  3  结束语

  MVC设计思想中的三部分是相互独立的,既可以通过不同的技术实现,也可以运行在不同的基础平台上。随着更多新技术的出现,还可以创造出更多的应用方式。所以MVC设计模式的确是一个创建软件的途径。

  本文所描述的只是MVC应用系统开发的一个基础模式。模型和视图严格分离的模式相对混合模式,对开发和设计人员的要求要高一些,但更容易进行错误控制。此外,在实际的应用中,开发者还要结合各应用项目的业务需要进行详细的设计规划,认真考虑应用的额外复杂性。只有把这些想法融进到架构中,才能增加应用的可拓展性。只有把握这一点,MVC模式才会使得应用系统更加健壮、更加灵活和更容易扩展。

 


  
上一篇:一种LV25-P电压传感器的设计和实现
下一篇:浅谈STRUTS框架应用对于Web服务扩展的作用

免责声明: 凡注明来源本网的所有作品,均为本网合法拥有版权或有权使用的作品,欢迎转载,注明出处。非本网作品均来自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。

相关技术资料