有许多朋友质疑这种MVC模式不正确。如果按照经典的MVC模式定义,这种实现确实是不正确的。
经典的MVC模式中,控制器仅仅是根据请求来决定调用哪一个视图,然后视图再调用模型来获取结果并显示。而我下面实现这种MVC模式,控制器要根据请求来决定调用哪一个模型,并传递参数给模型,然后获取结果。最后将结果传递给视图,视图只负责显示结果。
两种实现的比较如下:
经典MVC模式 | 异化的MVC模式 | |
---|---|---|
控制器 | 仅负责决定调用哪一个视图 | 需要负责调用模型,并将从模型获取的结果传递给视图 |
视图 | 需要决定调用哪一个模型,获取结果后显示 | 仅仅是显示传入的数据 |
模型 | 根据调用返回结果,不与控制器和视图发生关系 | 根据调用返回结果,不与控制器和视图发生关系 |
优点 | 分离表现层和业务层,控制器非常简单 | 分离表现层和业务层,视图非常简单,更容易和模版引擎结合 |
缺点 | 视图依赖于模型,容易将业务逻辑混入视图 | 控制器更复杂,容易将业务逻辑混入控制器 |
上面的表格简单比较了经典MVC模式和异化后的MVC模式之间的差别和优劣。
事实是,现在流行的PHP开发框架,都采用了异化后的MVC模式。因为异化后的MVC模式更容易和模版引擎结合,而且再配合Template View、Front Controller、Dispatcher等模式,能够进一步提高应用程序的结构化程度。
对于简单的应用程序,模型提供数据库CRUD操作,而控制器完成一部分业务逻辑操作。如果没有使用模版引擎,那么在控制器中使用include()就可以载入模版文件(视图)来显示结果。
对于复杂的应用程序,模型封装业务逻辑,而数据库操作则由数据源层负责。此时控制器只是调用模型获得结果,然后传递给视图。即便使用模版引擎,控制器也可以通过控制器基类的方法来处理。这样不但简单、代码量少,而且可以很方便的使用不同的模版引擎。
======================================
这个实例虽然简单,但是充分体现了 MVC 模式对分离“表现层”和“业务逻辑层”带来的帮助。
首先呢,还是有一个调度器,负责根据 HTTP 请求决定要调用的控制器:
PHP代码
- <?php
- require ('controller/' . preg_replace('/[^a-z0-9_]+/i', '', $_GET['controller']));
- ?>
一个控制器:
PHP代码
- <?php
- // 从 Model 获取数据
- require ('model/m1.php');
- $m = new m1();
- $data = $m->getData();
- // 构造视图,显示输出
- require ('view/v1.php');
- $v = new v1();
- $v->assign($data);
- $v->display();
- ?>
一个 Model:
PHP代码
- <?php
- class m1
- {
- function getData() {
- return 'hello';
- }
- }
- ?>
一个 View:
PHP代码
- <?php
- class v1
- {
- var $data;
- function assign($data) {
- $this->data = $data;
- }
- function display() {
- echo $this->data;
- }
- }
- ?>