白话 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的更多相关文章

  1. Android App的设计架构:MVC,MVP,MVVM与架构经验谈

    相关:http://www.cnblogs.com/wytiger/p/5996876.html 和MVC框架模式一样,Model模型处理数据代码不变在Android的App开发中,很多人经常会头疼于 ...

  2. Android App的设计架构:MVC,MVP,MVVM与架构AAAAA

    1. 架构设计的目的1.1 通过设计使程序模块化,做到模块内部的高聚合和模块之间的低耦合.1.2 这样做的好处是使得程序在开发的过程中,开发人员只需要专注于一点,提高程序开发的效率,并且更容易进行后续 ...

  3. MVC, MVP, MVVM比较以及区别(上)

    MVC, MVP和MVVM都是用来解决界面呈现和逻辑代码分离而出现的模式.以前只是对它们有部分的了解,没有深入的研究过,对于一些里面的概念和区别也是一知半解.现在一边查资料,并结合自己的理解,来谈一下 ...

  4. MVC, MVP, MVVM比较以及区别(下)

    上一篇得到大家的关注,非常感谢.一些朋友评论中,希望快点出下一篇.由于自己对于这些模式的理解也是有限,所以这一篇来得迟了一些.对于这些模式的比较,是结合自己的理解,一些地方不一定准确,但是只有亮出自己 ...

  5. android MVC && MVP && MVVM分析和对比

    相关:http://www.cnblogs.com/wytiger/p/5305087.html 出处http://blog.csdn.net/self_study,对技术感兴趣的同鞋加群544645 ...

  6. MVC MVP 和 MVVM的图示

    一直对于这些什么MVC MVP 和 MVVM都是云里雾里的 完全分不清楚 感觉jq上也没怎么用过,理解也很片面,画几张图也许能够大体分清他们之间的区别. 1.MVC(Model-View-Contro ...

  7. MVC, MVP, MVVM比较以及区别

    MVC, MVP和MVVM都是用来解决界面呈现和逻辑代码分离而出现的模式.以前只是对它们有部分的了解,没有深入的研究过,对于一些里面的概念和区别也是一知半解.现在一边查资料,并结合自己的理解,来谈一下 ...

  8. Android MVC MVP

    从.NET的宠物商店到Android MVC MVP   1 一些闲话 记得刚进公司的时候,我们除了做常规的Training Project外,每天还要上课,接受各种技术培训和公司业务介绍.当时第一次 ...

  9. [1] MVC & MVP &MVVM

    开发架构之MVC & MVP & MVVM  

随机推荐

  1. std::unique_ptr的用法

    std::ofstream("demo.txt") << 'x'; // 准备要读的文件 { std::unique_ptr<std::FILE, decltyp ...

  2. 数据库Oracle多表链接

    多表查询: 当查询的数据并不是来源一个表时,需要使用多表链接操作完成查询.根据不同表中的数据之间的关系查询相关联的数据. 多表链接方式: 内连接:(等值连接,非等值连接,自连接,SQL99有交叉连接( ...

  3. 2018HDU多校五-G题 Glad You Game (线段树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6356 Glad You Game  Steve has an integer array aa of ...

  4. Java多态之向上转型

    目录 Java多态之向上转型 多态的优点 向上转型 概念 向上转型好在哪 Java多态之向上转型 多态性是面向对象的第三大特征. 多态的优点 改善代码的组织结构和可读性. 能够创建可扩展的程序.(随时 ...

  5. Day 06 作业

    目录 Python基础实战之猜数字游戏 Python进阶实战之三级菜单 Python基础实战之猜数字游戏 给定数字,用户可以猜三次年龄 数字猜对,让用户选择两次奖励 用户选择奖励后可以退出 impor ...

  6. C语言每日一练——第1题

    一.程序功能 程序的功能是:将大于整数m且紧靠m的k个素数存入数组xx.并把in.dat文件的内容输入到程序,并把输出结果输出道out.dat文件夹中例如:若输入17,5 则应该输入:19,23,29 ...

  7. 《Java基础知识》Java变量作用域

    对于在作用域里定义的变量,作用域同时决定了它的“可见性”以及“存在时间”.在JAVA里,作用域是由花括号的位置决定的.JAVA用一对大括号作为语句块的范围,称为作用域,在作用域里定义的变量,只有在该作 ...

  8. python GUI编程tkinter示例之目录树遍历工具

    摘录 python核心编程 本节我们将展示一个中级的tkinter应用实例,这个应用是一个目录树遍历工具:它会从当前目录开始,提供一个文件列表,双击列表中任意的其他目录,就会使得工具切换到新目录中,用 ...

  9. Dubbo环境搭建-ZooKeeper注册中心

    场景 Dubbo简介与基本概念: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/103555224 注: 博客: https:// ...

  10. C# HttpClient以multipart/form-data形式 提交文件和其它参数

    调用文件接口,需要一个上传文件和一个Region参数,参考调用实例 public async Task<WebApiResult> UploadFile(UploadFileModel i ...