最近打算学习PHP框架,才发现我以前对MVC的认识很肤浅。但是看Laravel的文档,对MVC又是云里雾里的
以下答案属个人见解,若有错求大神指正。
先说下原生PHP吧。
数据处理,页面显示在一起,互相嵌套。
MVC就不一样,数据处理和展示是分开的。
业务不复杂的时候基本V和C就能搞定。
C哥把数据处理好,打包交给V。郑重的给V说:“V哥,数据都在这里了,您拿去显示吧!”
V说:“好的C哥!” 然后就把数据展现在前端。V哥也有类似foreach等的语法,用来展示C哥给的数据。
有时候业务复杂了,C哥一个人处理数据有点累,C哥就喊M哥来帮忙。
M哥帮C哥做一些重复性工作,处理好后给C哥。再由C哥转交给V哥。
原生PHP就像外包,往往一个人就得处理前端后端的东西。
MVC就像一个成熟的公司,有前端有后端。分工明确。
概念大家都说了,其实MVC的涵义一直在潜移默化地变化,原本CS软件的MVC和如今php ruby python讲的MVC已经有不小的区别了。甚至很可能概念早就变成MVP,只是大家习惯了MVC,指鹿为马了
我觉得已实际项目来说,作3个思想实验就能大致理解MVC的本质和目标,具体三层怎么分,是三层还是四层还是两层,其实都是为了达成灵活性和可维护性的手段而已
数据结构不变,把数据库从mysql迁移到pgsql乃至mongodb,你的项目需要多大的变化?
理想的MVC架构应该无需修改任何业务代码(包括Model),只需要修改配置文件,最多写个新的DBAL driver
实际情况下不同DB的能力有微妙的区别,那也应该微调Model就能解决。
如果你的答案是两眼一黑:和重写一遍差不多,那么你的M层还不够独立,该写在Model的代码分散到别处了
假设保持所有功能不变(都有合理自然的移动版交互),给你的站点增加手机版,你的项目需要多大的变化?
答案应该是重写一套View,然后Controller改一行if(isMobile) use(MobileView);
如果你发现Controller要改大量逻辑,甚至Model都被牵连,那你的V层不够独立
假设所有功能不变,给你的站点增加开放API(给第三方或移动应用使用),你的项目需要多大的变化?
答案应该是一套新的Controller 包含新的授权、和数据格式以及校验等逻辑,和一个简单的View(只输出json或xml)
如果你发现Model要改,原来View里的一些东西要挪动,或者是原来写在老的Controller里的部分代码要copy一遍,那么你的C层不够独立
最形象最简单的莫过于把MVC比作小时候玩的插卡式的游戏机:
M:就是游戏卡,保存数据,负责业务逻辑等
V:就是电视机,负责呈现游戏的画面
C:就是游戏控制手柄,负责前两者之间的交互
拿一个购物网站举例。
M提供了数据模型,比如网站的用户数据包括用户名,密码,邮箱,每个用户可以下多个订单,每个订单有订单号,价格等等。
V提供了视图,就是你看到的HTML界面是什么样的,比如商品列表的呈现,个人历史订单的呈现。
C是控制器,负责从M中提取数据,然后在V中如何呈现。比如你要查看最近一周个人订单历史的时候,V负责从M中找到你所有的订单,过滤掉一周以前的订单数据,然后把剩下的提供给V来展示。
理解mvc的前提是有代码分层的概念,而代码分层的目的是解耦。
请试图解答两个问题:
一个软件从用户触发视图上的业务需求,到程序按照一定的业务逻辑处理这个需求,再到将处理结果在视图的上反馈给用户,整个过程中的代码负责的主要任务有三个切面,即:视图的操作,业务逻辑的处理,视图和业务逻辑之间的对接。
在程序中如果代码不分层的话,那么这个三个切面的实现会耦合在一个类中。为了代码的可维护性、可读性、灵活性(请参看@mcfog的答案),就应该将这些代码按照切面分别写到不同的类中,进而将相同切面的类放到一个包中,这些类和包看起来像在不同的层面上。
mvc是成熟的分层(解耦)方案。
根据第一个问题的回答,要将不同层面的代码放到不同的类(和包)中,那么这些不同层次的代码如何协作?
此问题的其他答案看样子已经具体地,并且图文并茂地回答了这个问题。
Model中的代码负责业务逻辑;
View中的代码负责用户交互;
Controller中的代码负责model和view的对接。
越简单越好是吧?
M:模型——你如何为数据建模,或者说你的数据用何种结构表示
C:控制器——你如何处理业务逻辑,这个“处理”主要是对应两个端:一端是向模型请求处理需要的数据来源;另一端则是把处理结果用某种方式传递给视图;中间的具体过程就是控制器负责的层面
V:视图——你如何向客户端呈现业务处理的结果以及提供交互
其实说的太简单了也不好,因为有些细节为了简化只能高度概括和抽象,若是没有足够的知识和经验支撑就如同雾里看花。
看了楼上各位的回答,最后觉的:V是给用户看的 C是给用户控制的 M是用户接触不到的 通过C和V对M进行控制?
SO上关于MVC的讨论:What is MVC, really?
C和V是人机界面,C是人机界面的功能部分,V只是呈现形式,把它从图形换成命令程序还能跑,只不过不直观而已。一方面M是供C调度的资源,另一方面M是程序中与人机交互不直接相关的部分,它往往需要C来驱动,但是一经驱动就可以独立运行。很多时候大家谈论MVC时都矮化了M,认为它只是对数据的封装,是静态的,其实这只在逻辑较简单的情况下才成立,这时候似乎可以把逻辑都塞进C中。但是一般情况下,相比于M,C是很轻的,因为它只负责人机交互,而M则是程序的主体部分。
顾客到餐厅点菜,顾客点好了,服务员要告诉传菜员,传菜员再告诉后厨。
M--菜
V--服务员(菜单)
C--传菜员
M(菜)应该直接跟后厨打交道,那么后厨就是项目里的Service了。
另外:一些比较low的餐厅,会把服务员和传菜员当作一个人来用。
这就是JAVA项目里的,在JSP里写业务逻辑的作法。
有些更low的餐厅,只有一个老板,这个老板身兼服务员、传菜员、后厨。。
这就是JSP里写数据操作的作法。
所以高级餐厅里,会有各种各样的角色,细分至极。提高效率,提高可维护性。这就是为嘛大餐厅实习生多的原因了。
老板说,想看一下这个月的销售情况。这是一个请求。于是你(C)接受了这个请求,要公司各业务部门(M)提供这个月的所有销售数据,然后把这些数据做一下简单整理交给了老板助理(V)。老板助理用这些整理好的数据按部门做成图表饼图呈交给老板看。
mvc的关键,就是路由!!!,路由不懂???就是拆分url地址,剩下的那些,等你写过几个controller的增删该查就渐渐明白了
所以研究mvc,研究路由,就是拆url地址,打完收工!
比如说写一个 Todo List, 按照前端的 MVC 这样写:
一般有这样的关系(不是很准确, 而且各种 MVC 实现也不完全一致):
整体上是一个循环~ 从 Model 开始, 中间加上用户操作, 又作用回到 Model
这是写图形的一个思路, 就是把数据跟界面区分开来, 简化程序.
或者说, 抽象出表示一个界面最少的数据作为 Model, 最少的操作作为 Controller.
而 View, 跟着 Model 变, 甚至根据用户需要随意进行改变.
大致上:
或者: