本文原来是为了回答一个网友的问题 (何为MVC?应用smarty后,也只有mv,那里来的C呢?)http://www.phpchina.com/bbs/viewthread.php?tid=51395&extra=&page=1
现把它整理成一篇文章,方便阅读。

====================================================
问题 :何为MVC?应用smarty后,也只有mv,那里来的C呢?
------------------------------------------------
goodonyou:

MVC是一种OO开发模式,比较多的用在GUI (Graphic User Interface)系统里。因为PHP面向web编程,采用MVC模式是很自然的了。在MVC模式里,用户界面可以看成是V (view),也就是浏览器里呈现出来的东西。C (controller) 可以是界面里的按钮,输入栏,等等;也可以是程序里预定的控制程序。 M (model) 就是响应每一个C 的应用程序。比如,用户进入一个登陆页面 V,V 里面有一个表单,两个输入栏,要求用户输入用户名,密码,然后按登陆按钮,登陆按钮就是一个C,C再调用M,M的作用就是把用户输入的数据与数据库里提取的数据作比较,如果正确,就把正确的信息传给V,如果不正确,就把不正确的信息传给V。

不用smarty也可以用MVC模式,用了smarty后,就是在V里面把PHP代码与HTML代码分开而已。假如用了smarty后只有MV,没有C,是因为你没有用MVC模式来开发,没有建立C控制层的概念。

MVC模式是OO编程中的一种设计模式,一种贯彻方法,一种思路。核心思想是将表现逻辑层和应用逻辑层分开,并利用控制层来进行控制调度,以达到将复杂问题简单化的效果。没有框架也可以用MVC模式编程。

MVC要它的优势,也有其局限的地方。希望大家对其有了比较深入的了解后,能扬长避断的使用。

-------------------------------------------------------------------------
M同学:

我是这样理解的:
M是一个或多个类,每个类里封装了对一个或多个数据表进行增、删、查、改的若干个方法。C用来接收客户端发来的get、post信息,然后调用M里相应的方法,进行数据库的存取等操作,然后将响应结果传递给V来输出html
------------------------------------------------------------------------
goodonyou:

这样理解没错。因为书本上就是这么讲的。但是我也向你提个问题:根据你的理解,能说说怎么用MVC方法来贯彻一个页面呢?比如我说的那个登陆页面?:-)

-------------------------------------------------------------------------
M同学:

1. 显示“输入用户名和密码”的html页面:
   C判断没有post任何数据进来,则调用V来显示“输入用户名和密码”页面
2. 接收了用户输入的用户名和密码:
   C判断post进来了用户名和密码,然后C调用M查询用户名和密码是否匹配,如果匹配,C调用V显示“登录成功”等信息,如果不匹配,C调用V显示“用户名或密码错误”等信息

在这里M用来进行对用户表(记录用户名和密码等信息的表)的增删查改等操作,V用来生成html,C用来根据get、post来控制程序的运行流程

--------------------------------------------------------------------------
goodonyou:

M同学说的不错,谢谢你。但感觉有点像是从过程编程的角度来分析的,而不像是从OO的角度来分析的,是否如此,M同学能否给大家解释一下吗?比如说你打算怎么用函数或类来实现这些要求,假如用类,怎么能尽量做到代码重用?你感觉这种做法(函数或类)有那些好处,那些缺点?

--------------------------------------------------------------------------
M同学:

//m.class.php
class M($db)
{
  private $_db;

public function __construct($db)
  {
     $this -> _db = $db;
  }

public function add($param)
  {
     ...
  }

public function delete($param)
  {
     ...
  }

public function get($param)
  {
     ...
  }
 
  public function modify($param)
  {
     ...
  }
}

//v.class.php
class V extends Smarty
{
  public function __construct()
  {
    ...
  }
 
  public function display($tpl, $title = null)
  {

$this -> assign('title', $title);
      parent::display($tpl);
  }

...
}

//v1.class.php
class V1 extends V
{

public function display()
  {
     parent::display('v1.htm', ‘....’);
  }
 
}

//c.class.php
class C
{
  static $m = null;

public function xxx()
  {
     $v = new V1();

$m = $this -> _getModel();
     $v -> assign('var', $m -> get(......));
     $v -> display();
  }

public function yyy()
  {
     ...
  }

public function zzz()
  {
     ...
  }

private function _getModel()
  {
    if (!is_null(self::$m))
    {
       self::$m = new M();
    }   
    return self::$m;
  }

public function __construct()
  {
     //根据query string判断调用哪个方法(xxx、yyy还是zzz)
  }
}

//index.php
require(.......);
require(.......);
require(.......);
...
$c = new C();

我的程序里类似是这样的,M里的方法可以被不同的C重复使用,C因为是根据query string来判断运行哪个方法的,所以做不到重用。没看过别人的代码,不知道他们是怎么写的。

--------------------------------------------------------------------
goodonyou:

你这个MVC的架子做的不错。我想你也是刚学OO不久,能做成这个样子,真要恭喜你了。
不过有几点看法,提出来跟你和大家共同讨论一下。

1。OO代码的重用性和扩展性。
代码能尽可能做到重用与容易扩展,是体现OO语言优势的一大特色。把MVC架构用于web的开发,意味着几乎每个页面都要用到MVC。因此我们在设计类 (class)时就要设法尽可能做到代码重用;又因为每个页面都不同,因此又要想办法做到这个类容易扩展。(如果谁认为在他的项目中无法做到这两点,那就考虑不要用OO了。)

结合你的例子,我认为如果把每个页面里的每个M,V,C里共同需要的内容和参数放在一起,做成一个父类的M,V,C; 到了实施具体页面时,我们再做一个子类的M,V,C,差异的部分在子类里贯彻,这样我们就能较好的贯彻了代码的重用性和扩展性了。

2。MVC架构每部分的功能
这点我们在上面的帖子里已经在理论上讨论过了,到了实际应用时,又可能要根据项目的具体情况,对每部分包含的内容作适当的调整。

对V部分,V主要是用来表述要显示的内容或数据。可能是HTML数据,可能是XML数据,可能是图表数据。。。表现的方法和格式也是多种多样的。V就是用来处理这些问题的。在你的例子里,V只是用来调用一个smarty模板。如果所有项目都是用HTML 和smarty来表现数据的话,我觉得调用模板的功能,放在C里来控制似乎更好一些。 (考虑到以后扩展性的话,也可以把它分开)。 V可以把重点放在如何表现数据上面。

对M部分,在Java里面,M主要是用来处理数据层的,因为Java里数据层包含的内容多且复杂,如RDMS,mail server, directory service. message queue 等等,业务层一般就用Javabean来做了。在PHP里没那么复杂,就把它们都包括了。但是一般都分为数据处理和业务处理两部分。业务复杂的,业务处理部分再细分,如产品类,订单类,等等。在你的例子里,这个M似乎只处理数据层,不处理任何业务逻辑。因为在这个简单的例子里,业务逻辑简单(只有 get_data() 和 compare()两部分),所以放在C里也可以,但这种设计,在以后碰到复杂的业务逻辑时,C就会不负重荷了。

对C部分,主要用于页面流程的控制调度。本身不处理业务逻辑。所以,在你的例子里,似乎没有必要设计三个函数(xxx, yyy,zzz),这是属于M的东西。

C可能的实现方法之一:

class login_controller extends Controller
{
private $input;
public $result;
public $output;

function check_input($input){ //这部分也可以独立出来, 设一个类。
$this->input = new check_input($input);
}

function dispactch(){  //根据需要调用不同的model
switch($this->input){ //在类里面,一般尽可能不要用这种条件语句,可使用继承方法产生子类,这里我偷懒一下。
case a:
$this->result = new login_model_a($this->input);
case b:
$this->result = new login_model_b($this->input);
。。。
}
}

function display(){
$this->output= new login_view($this->result, DISPLAY_TYPE);
}
}

用MVC的好处:

* 各施其职,互不干涉 --在MVC模式中,三个层各施其职,所以如果一旦哪一层的需求发生了变化,就只需要更改相应的层中的代码而不会影响到其它层中的代码。

* 有利于开发中的分工 -- 不用多解释了。
    * 有利于组件的重用 -- 不用多解释了。
    * 有利于项目的反覆修改 -- 改变或增加功能时,加一些class就行了,不用在原代码上翻来复去的改。

缺点:

* 学习曲线长
    * 设计难度大 -- 设计的不好,会导致代码的重用性和扩展性差,还不如用面向过程编程,我想这也是很多人抱怨OO编程的原因之一吧。
    * 模型和视图的分离使调试比较困难,但容易发现错误
    * 代码文件增多,项目开始阶段,化的时间肯定比过程编程多

综合上述,如果能把握的好,MVC模式会使得你的应用更加强壮,更加有弹性,更加个性化。

限于本人的水平有限,说的不对的地方,请大家批评。

MVC的概念及其在PHP中的贯彻简介相关推荐

  1. Spring MVC普通类或工具类中调用service报空空指针的解决办法(调用service报java.lang.NullPointerException)...

    当我们在非Controller类中应用service的方法是会报空指针,如图: 这是因为Spring MVC普通类或工具类中调用service报空null的解决办法(调用service报java.la ...

  2. c++中的异常--1(基本概念, c语言中处理异常,c++中处理异常,异常的基本使用,栈解旋)

    异常基本概念 异常处理就是处理程序中的错误,所谓错误是指在程序运行的过程中发生的一些异常事件(如:除0退出,数组下标越界,所要读取的文件不存在,空指针,内存不足等等) c语言中处理异常 两种方法: 使 ...

  3. 以数制转换问题讲解栈数据结构的基本概念及其在计算机中的应用

    以数制转换问题讲解栈数据结构的基本概念及其在计算机中的应用 一.栈的概念介绍 在我们的生活中,总有这么一些例子,①食堂在堆放餐盘的时候,总是从下往上,在取餐盘的时候,又是从上往下:②最先放入厢式货车的 ...

  4. 『深度概念』度量学习中损失函数的学习与深入理解

    『深度概念』度量学习中损失函数的学习与深入理解 0. 概念简介 度量学习(Metric Learning),也称距离度量学习(Distance Metric Learning,DML) 属于机器学习的 ...

  5. Spring MVC普通类或工具类中调用service报空空指针的解决办法(调用service报java.lang.NullPointerException)

    当我们在非Controller类中应用service的方法是会报空指针,如图: 这是因为Spring MVC普通类或工具类中调用service报空null的解决办法(调用service报java.la ...

  6. C的几个小程序和概念(常见操作)(中)

    C的几个小程序和概念(常见操作)(中) 1.求和计数 (1)常见的有三种方法:累乘,累加,递推迭代法. (2)求Pi/4=1-1/3+1/5-1/7+... 正负交叉项数列.用一个符号变量来实现. a ...

  7. ASP.NET MVC应用迁移到ASP.NET Core及其异同简介

    ASP.NET Core是微软新推出支持跨平台.高性能.开源的开发框架,相比起原有的ASP.NET来说,ASP.NET Core更适合开发现代应用程序,如跨平台.Dorker的支持.集成现代前端开发框 ...

  8. python中set()函数的用法,python中set()函数简介及实例解析

    python中set()函数简介及实例解析 set函数也是python内置函数的其中一个,属于比较基础的函数.其具体介绍和使用方法,下面进行介绍. set() 函数创建一个无序不重复元素集,可进行关系 ...

  9. Python中的JSON简介

    您知道如何从在线API传输数据或将不同类型的数据存储到本地计算机吗?无论以何种方式,您都会沉浸在JSON中,JSON代表[Java Script Object Notation].它是一种著名的流行数 ...

最新文章

  1. PPStream、PPlive等播放器花屏之解决办法
  2. 通俗易懂理解PBFT拜占庭容错的回答
  3. boost::hana::at_key用法的测试程序
  4. 图解ARP协议(六)RARP与IARP:被遗忘的兄弟协议
  5. Spring+Mybatis多数据源配置(二)——databaseIdProvider的使用
  6. 征信上显示保险代偿记录,那你的信用基本就黑了
  7. Nmap配合Masscan实现高效率扫描资产
  8. 前端架构之路:使用Vue开始第一个项目
  9. 一个程序员开始优秀的 3 种迹象
  10. 工厂方法(Factory Pattern)
  11. 可调稳压电源lm317实验报告_LM317可调稳压电源实训实验.doc
  12. 项目研发过程中甲方要增加合同外的需求,项目经理该如何处理?
  13. 马化腾:这一类中层干部,我最多忍你半年
  14. Debian11 安装Chromium浏览器
  15. 九度[1029]-魔咒词典
  16. 紫光视频平台服务器系统,紫光展锐打造操作系统生态,赋能万物互联智能时代...
  17. C++程序调用第三方exe进程(例如Go语言开发的程序)
  18. mmclassification使用步骤与心得/ACCV实验记录
  19. 基于51单片机的温湿度检测及调节系统
  20. Google基础设施架构的安全设计

热门文章

  1. python如何解决报错:‘platformVersion’ must be of type string
  2. ios 对应 iphone_带有iOS 14的iPhone终于出现了浏览器选择
  3. .net core 中 Redis 入门
  4. 面向更高阶自动驾驶!地平线RDK X3怎么玩?新板试用就是现在!
  5. 你领证了吗?各地2022下半年软考纸质证书发放中
  6. Gartner 2020年十大技术趋势之一:超级自动化
  7. png 与jpg的区别
  8. 每周读书#8 - 《写给大家的西方美术史》
  9. 云计算机运维是什么意思,什么叫云技术?
  10. 【笔记】计算机网络-数据链路层