详情请直接查看: 我的个人博客
写在前面
本篇对于MVC框架的一部分总结,原有为MVC课程作业,更大的原因是自己想完成一份关于MVC的使用总结。其中涉及较为简单的.NET MVC 以及 ThinkPHP5.1 等内容,不够更多的便是对于MVC的了解。
本文共花费三个小时,阅读大约需要15分钟。
本人拙,如有错误还请留言指出。
引言
MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。
正文开始
先给个MVC的抽象图。
MVC中的C值得是控制器(controller),虽然叫做控制器,他负责的东西并不多,只是在View(即MVC中V)和Model(MVC中M)之间相互传递数据。当然,其最大的用处就是View和Model之间的解耦。
例如,用户想在文章下方评论,用户发表评论后数据传到 Comment 的 Controller,然后 CommentController 将数据发送到相应的 CommentModel,经过处理后返回至 Controller 然后获取数据判断一下是否评论成功了,成功了就返回成功的 View 视图,不成功就返回到不成功的View视图。
对!如果我们业务逻辑修改了,我们现在想用户评论后自动点赞,或者评论成功后就关闭窗口(当然这种需求并不合理),那我们只需要修改 Controller,让他导向点赞的 Model,或者获取 Model 返回的数据后关闭窗口。** 所以,controller并不是一个写业务逻辑的地方!! **
MVC中的 V 指的是视图,简而言之就是我们的 HTML 网页,就是我们直接呈现给用户的界面,就是脸。View 就是在获取到来自 Model 的数据并显示出来,当然你也可以说获取到来自 Controller 的数据(因为 Controller 在他们之间传递数据)。
MVC中的 M 指的是模型,模型就是我们数据库里面示例出来的数据库中的表,我们在Model里面写业务逻辑。那什么是业务逻辑?比如,用户注册后存入数据库的时候,用户名字段应该是用户输入的用户名加上当前日期拼成的字符串,而拼接字符串就是业务逻辑。
几乎我们所有的业务逻辑都会写在 Model 里面,当我们需要改变某些业务逻辑的时候,我们只要重写相应函数的代码就可以了。
讲道理
我们刚刚说到了 Model 层来写业务逻辑,但是作为小白的自己开始的时候不知道是对C这个字符的好感,还是不明白业务逻辑是什么的原因,天经地义的以为 Controller 就是写业务逻辑的。
当时的心态应该是这样的:controller 控制器!控制整体的部件哎!多厉害!他就是要写的越多越好!
后来自己再用 ThinkPhp(也是 MVC 框架)时,猛然间觉得有点问题,看着 controller 层慢慢变大,在调用共用的 controller 里面的方法时觉得这也太奇怪了吧,而 Model 层一个 S (save)的操作,竟然要调用控制器里面两个数据来处理 View 层用户提交的数据,而且想修改存储内容的时候,尽然要修改 Controller 的内容,这不禁让我觉得我这种做法极其愚蠢…
看了几篇前辈的文章,讲道理对于MVC似乎更清楚了许多。这里整合了网上部分内容,做简单的总结,认为对的改之放之,认为错的弃之。
- 同一个 Model ,可以对应多个 View , 同一个 View 可以得到不同的 Model 数据 ,大大增加model的重用。MVC 严格分开了 Model 和 UI 组件,因此 Model 与 View 是多对多的关系 。而我们将业务逻辑层写在 controller ,那这种解耦的效果就不存在了,因为 Model 就只能单纯的写入数据库,读取数据库了。
- 易解决需求变动问题。我们只需要重写 Model 里面某些函数的代码,然后controller层引用一下就可以了。这似乎更加体现了解耦的效果。
3.“可插拔”的 View 和 Model ,让你可以把与 Controller 对应的 View 和 Model 组件更换掉。
文章原话:“可插拔”的 view 和 controller MVC 这三种概念上的区分,让你可以把与 Model 对应的 View 和 Controller 组件更换掉,甚至是在运行时这么做都没问题。
当然还有其他优点,精力有限写在这里。
** 总结来说:我们将业务逻辑写在 Model 而不是 Controller 可以大大解耦 View 与 Model 的联系。 **
三层架构是界面层(UI)业务逻辑层(BLL)和数据访问层(DAL)构成的,而MVC是模型层(M)界面层(View)和控制层(Controller)构成的,而且他们之间也不对应。可能是受到三层构架的影响,将 UI 当成了 View ,将 BLL 当成了 Controller ,将 Model 当成了 DAL …似乎没什么不对的!全错了…最后将业务逻辑写在了Controller, 变成了四不像!
既然知道了是因为三层架构与MVC的混淆,我们似乎必须弄懂三层架构是什么才能更好的去理解MVC。图:
MVC和三层架构似乎真的有些联系,而并不是我所认为的联系。根据上面的图我们可以很清楚的明白MVC到底和三层架构的对应关系。
** 总结:三层架构与MVC核心都是为了分层、解耦,实际内容是差不多的,只不过划分的方式有些差别而已。 **
MVC加入VM
现在我们数据库里面有个 考试 的数据库,然后每份试卷有题目信息,我们数据库里面有 ** 考试 ** 和 ** 题目 ** 两张表,现在我们查看试卷信息的时候我们还想看到它里面的题目信息例如:
而我们的 Model 只能返回一个表里面的信息,我们需要其他的 ** 类 ** 来储存两个以上的数据表信息,当然我们也可以引入其他的,比如我们设置一个分布视图单独出来也是可以的。但如果我们想要在题目上显示这是那个试卷上的题目呢?分布视图似乎也得需要传入两个字段才能解决。
图中网站来自 Day Day Up
这时候我们需要一个能够存储 ** 多个数据字段 ** 才能解决需求的Model,那就将 View Model 引入吧!
ViewModel 顾名思义,就是作用在View层的Model(当然这句话并不严谨),我们在控制器里面将获取到的多个 model 数据,实例化成一个 ViewModel ,然后在传入视图。这种方法似乎很有效,而且我们完全可以根据我们的需求来新建 ViewModel ,控制它的个数。
例如,刚才的例子我们完全可以新建一个名为 TestQuestionsViewModel 的ViewModel:
public class TestQuestionsViewModel{
public Test test{get;set;}
public List<Question> questions{get;set;}
}
这样我们就可以直接实例化一个既包含test信息又包含test里面question信息的 “Model” 了。
ViewModel 并不是真正的 Model ,它更像是一个Temp(临时变量)。
结尾
如有错误望评论指正。