白话 MVC、MVP、MVVP
白话 MVC、MVP、MVVP
注意这里单纯的通过例子来讲解 MVC
MVP
MVVP
这三种架构模式的起源和作用,不牵扯某种特定的语言。具体到各种语言各种软件系统上体现有所不同,但是原理都是这样的。清楚原理最重要
假设要开发一款软缘分指数软件,软件如下图:
输入男生姓名和女生姓名后,点击按钮即可计算出缘分指数,就是这么一个软件。当然本身这个软件非常简单,但是为了更好的演示,不可能真的举出一个大项目的例子,由于这个软件本身过于简单,真正设计架构的话反而显得很鸡肋,因此你要想象成这个软件十分复杂!不然容易产生这么设计架构有什么用的想法。
起始阶段
最初阶段,程序员小明写这个软件的时候什么都没有想,直接上手码代码了,结果用于展示页面的代码,用于获取用户输入内容的代码,拿到用户输入的内容来计算缘分指数的代码,等等代码业务全部写在了一个文件中。完成了本软件的开发。
结果过了一段时间小明离职了,小华来接手他的代码,小华看到这个代码的时候,默默的留下了眼泪,一个文件中足足有 1 万多行代码,各种功能的代码彼此混合在一起,完全是大杂烩,想要修改一个地方根本不敢动。于是小华决定自己重新来写,因为这个大杂烩已经不可能维护了,改动比重写代价还要大!
MVC
小华是这样给这个程序分类的:
- 首先是页面,页面可以单独抽离出来
- 一些和页面判断有关的逻辑,比如:如果什么也没有填写的话,点击按钮是不会进行业务计算的。获取用户输入后去调用具体的业务逻辑的操作
- 具体的计算缘分指数的的业务(需要查询大量数据得出)
页面部分用 V 来代表,只负责与页面有关的操作,比如按钮的摆放位置,计算出结果后页面的变化更新等等与页面有关的操作。
控制页面上的逻辑和调用具体业务逻辑的操作用 C 来代表,在 C 中只负责接收 V 的指令,然后调用业务逻辑,和操作 V
计算具体的与数据有关的业务逻辑用 M 来表示。
小华就按照这种方式来进行书写代码,这样写出来的代码可读性非常高,各层之间互相分离,不再是大杂烩了。而且分工也容易,写页面的写页面,写业务逻辑的写业务逻辑等等。
上面这样设计的流程图是这样的:
当然,你在网上可以还看到过其他的设计图,各种各样的都有,其实这个就看作者是怎么想的了,这个没有标准答案。主要的思想就是分层了,不再大杂烩了,至于它们之间的相互关系,就看你具体代码的体现了。
其实 MVC 在真正大型运用的时候,最接近这种
也就是说如果不触及复杂逻辑或者数据的情况下,一些简单逻辑就直接在 Controller
处理了,然后 Controller
再作用于 View
。还有一点就是 MVC
中 View 是可以和 Model 直接进行交流的。
当然如果你非要切断 Model 和 View 之间的关系的话,那样就演变成 MVP 了。
这就是 MVC 的雏形
M 表示 Model 专门用来做一些和数据(联网数据、本地数据、复杂逻辑)有关的逻辑
V 表示 View 专门用来控制页面的
C 表示 Controller 获取用户的输入,操作 M 和 V,说白了就是调用 M 和 V 中的方法
MVP
又过了一段时间,小华发现这种架构方式虽然比之前的大杂烩好很多,但是 M V C
之间相互依赖过多,由于 View 可以和 Model 直接通信,这就造成了 View 既依赖于 Controller 又依赖于 Model 。Controller 同样依赖于 View 和 Model。耦合性还是太高,于是进行了进一步的优化处理。让 M 和 V 彻底断了联系,只通过 P 来进行通信。
这样 P 操作 Model,在 Model 中进行业务计算后得出结果,让Presenter 再去更新 View。
public void updateView(){
view.setText("xxxxxx");
}
这样Presenter 对 View 有依赖,这样 Presenter 就没法进行单独做单元测试了,必须等页面好了以后才可以(不然没法调用页面里面的方法)。于是进一步优化,让 View 层提出接口,Presenter 只依赖这个接口(接口很好写),这样页面还有完成也可以进行测试了。
通过接口也降低了耦合性,其他的页面也可以实现这个接口。
MVVM
MVP 使用一段时间后,发现让 Presenter 调用 View 的方法去设置界面,仍然需要大量的、烦人的代码。
于是提出:能不能告诉 View 一个数据结构,然后 View 就能根据这个数据结构变化而自动随之变化呢?
于是有了一个叫 ViewModel 的东西,它可以和 View 层绑定。ViewModel 的变化,View 立刻就会变化。
那么什么是 ViewModel 呢?继续拿上面那个例子举例,ViewModel 差不多是这样的:
public class SalaryViewModel{
String sex; // 性别,和 View 中的相关字段对应
String index; // 姻缘指数,和 View 中的相关字段对应
//.....
}
当用户在界面上点击「计算」按钮的时候,只需要对 ViewModel 做出改变就行了。View 会根据 ViewModel 的变化做出更新,不用手工去设置。
ViewModel 和 View 的绑定问题,需要开发一个框架让两者绑定起来,微软的 WPF 和 Silverlight,Android 等框架和系统都可以实现 View 和 ViewModel 之间的映射和绑定。
到此整个架构的设计就非常合理了,代码维护起来也比较容易,可阅读行比较高!
总结
再次强调上面讲的都是 MVC
MVP
MVVP
大的设计思路,具体到不同的语言程序体现起来是不同的,没有准确的定义,具体的书写方式要根据开发者自己的思想来定义。目的就是让代码不同功能间相互独立,可阅读性强,便于扩充和重复利用。
一切不结合项目和实际问题空谈架构的行为都是耍流氓
切记不能为了架构而架构,项目较小的情况下,硬搬乱套架构只会增加你的代码量,导致非常冗余,这种情况下还不如好好提炼几个方法更容易查看维护。
起初写的代码全部混合在一起非常冗余不便于维护(当然如果说你写的时候做了某种抽离和分层,那么这就是你的一种架构思想),为了解决这个问题提出了 MVC 的架构模式,极大的解决了混为一滩的情况,但是这种思想设计之初 M 和 V 之间是可以相互通信的,导致了依赖关系太多,就出现了 MVP,MVP 出现后解决了 M 和 V 之间通信的情况,让 M 和 V 彻底失去关系,由 P 来通知 V 进行修改,再后来每次 P 还要通知 V 进行修改太麻烦就想法当 M 中的数据发生变化的时候直接修改 V 中的视图通过 ViewModle 来实现,这个时候就出现了 MVVM。
下面一篇文章来讲解这几种模式在 Android 开发中的具体体现。
白话 MVC、MVP、MVVP的更多相关文章
- Android App的设计架构:MVC,MVP,MVVM与架构经验谈
相关:http://www.cnblogs.com/wytiger/p/5996876.html 和MVC框架模式一样,Model模型处理数据代码不变在Android的App开发中,很多人经常会头疼于 ...
- Android App的设计架构:MVC,MVP,MVVM与架构AAAAA
1. 架构设计的目的1.1 通过设计使程序模块化,做到模块内部的高聚合和模块之间的低耦合.1.2 这样做的好处是使得程序在开发的过程中,开发人员只需要专注于一点,提高程序开发的效率,并且更容易进行后续 ...
- MVC, MVP, MVVM比较以及区别(上)
MVC, MVP和MVVM都是用来解决界面呈现和逻辑代码分离而出现的模式.以前只是对它们有部分的了解,没有深入的研究过,对于一些里面的概念和区别也是一知半解.现在一边查资料,并结合自己的理解,来谈一下 ...
- MVC, MVP, MVVM比较以及区别(下)
上一篇得到大家的关注,非常感谢.一些朋友评论中,希望快点出下一篇.由于自己对于这些模式的理解也是有限,所以这一篇来得迟了一些.对于这些模式的比较,是结合自己的理解,一些地方不一定准确,但是只有亮出自己 ...
- android MVC && MVP && MVVM分析和对比
相关:http://www.cnblogs.com/wytiger/p/5305087.html 出处http://blog.csdn.net/self_study,对技术感兴趣的同鞋加群544645 ...
- MVC MVP 和 MVVM的图示
一直对于这些什么MVC MVP 和 MVVM都是云里雾里的 完全分不清楚 感觉jq上也没怎么用过,理解也很片面,画几张图也许能够大体分清他们之间的区别. 1.MVC(Model-View-Contro ...
- MVC, MVP, MVVM比较以及区别
MVC, MVP和MVVM都是用来解决界面呈现和逻辑代码分离而出现的模式.以前只是对它们有部分的了解,没有深入的研究过,对于一些里面的概念和区别也是一知半解.现在一边查资料,并结合自己的理解,来谈一下 ...
- Android MVC MVP
从.NET的宠物商店到Android MVC MVP 1 一些闲话 记得刚进公司的时候,我们除了做常规的Training Project外,每天还要上课,接受各种技术培训和公司业务介绍.当时第一次 ...
- [1] MVC & MVP &MVVM
开发架构之MVC & MVP & MVVM
随机推荐
- 产品vs程序员:你知道www是怎么来的吗?
精彩回顾: 我是一个explorer的线程 我是一个杀毒软件线程 我是一个IE浏览器线程 比特宇宙-TCP/IP的诞生 Unix.Linux.Windows三大帝国集团发表<关于比特宇宙推进经贸 ...
- Python的Requests库基本方法函数
一.Requests 库的七个常用函数: 1. requests.request(method,url,**kwargs) :method:请求方式,对应get/put/post等七种 :拟获取页面的 ...
- luogu P1807 最长路_NOI导刊2010提高(07)
题目描述 设G为有n个顶点的有向无环图,G中各顶点的编号为1到n,且当为G中的一条边时有i < j.设w(i,j)为边的长度,请设计算法,计算图G中<1,n>间的最长路径. 输入格式 ...
- luogu P3807 【模板】卢卡斯定理
求 C(n,n+m)%p C(m,n)%p=C(m%p,n%p)*C(m/p,n/p) #include<cstdio> #include<cstring> #include& ...
- 微服务管理平台nacos虚拟ip负载均衡集群模式搭建
一.Nacos简介 Nacos是用于微服务管理的平台,其核心功能是服务注册与发现.服务配置管理. Nacos作为服务注册发现组件,可以替换Spring Cloud应用中传统的服务注册于发现组件,如:E ...
- Mybatis的模糊查询以及自动映射
Mybatis的模糊查询 1. 参数中直接加入%% ? 1 2 3 4 5 6 7 8 9 param.setUsername("%CD%"); param.setP ...
- CoderForces Round60-(1117A,1117B,1117C题解)
A. Best Subsegment time limit per test 1 second memory limit per test 256 megabytes input standard i ...
- 【HTML5】296- 重新复习 HTML5 的 5大存储方式
点击上方"前端自习课"关注,学习起来~ 一.介绍 在 HTML5 规范之前,存储主要是用 cookies . cookies 的缺点有: 在请求头上带着数据: 大小是 4k 之内: ...
- Android Studio 中java 文件报错红色J
用常用的方法清除Android Studio的缓存然后重启,"File" -> "Invalidate Cashes / Restart" -> & ...
- 解读setTimeout, promise.then, process.nextTick, setImmediate的执行顺序
最近在看<Node.js调试指南>的时候遇到有意思的几道题,是关于setTimeout, promise.then, process.nextTick, setImmediate的执行顺序 ...