以后篇文章前面我都会总结一条最新的新闻,争取言简意赅,让您花费最少的时间了解最新的信息。
每日新闻News
Google Lens 2017年google I/O 大会上推出的一项AI技术,简单的解释:用户可以通过手机相机即可了解眼睛所看到的一切,例:拍到花就知道花的相关信息、外语标识的公告牌信息等等。
目前只有谷歌旗下的手机和三星的Galaxy s9/8 Note 8 有这个功能,但是据最近的IT之家,从Reddit论坛中网友中表示可以在一加手机的3/3T/5T中的google智能助理应用中使用Google Lens功能。
MVC简介
还是按照大家熟知的思维方式,我们先附一张图:
MVC结构图
网上盗的图,请原谅笔者偷懒了。关于MVC经典的图片应该是这样的:
但是我认为,第一张图要形象一点,我相信这样更加的方便认识MVC框架。
MVC的全名是Module View Controller ,从图中也可以看出MVC主要分为3层:
(下面将Module简称M层,View简称V层,Controller简称C层)
M层:适合做一些业务逻辑处理,比如数据库存取操作,网络操作,复杂的算法,耗时的任务等都在model层处理。
V层:应用层中处理数据显示的部分,XML布局可以视为V层,显示Model层的数据结果。
C层:在Android中,Activity处理用户交互问题,因此可以认为Activity是控制器,Activity读取V视图层的数据(eg.读取当前EditText控件的数据),控制用户输入(eg.EditText控件数据的输入),并向Model发送数据请求(eg.发起网络请求等)。
今天这篇文章的主要的学习内容:如何将MVC的三个层划分出来,让我们能更清楚地知道,M层、V层,C层分别的职责是什么,这样才能更加有助于理解MVC。
MVC结构
看过我第一章节的朋友应该都知道,我描述了一个场景Android MVP系列(一),可以回顾一下。
既然MVC分为三个部分,那我们就来逐个击破,按照M、V、C的顺序(这个顺序是有一定意义的),先来介绍M层:
Module 层
问
可能有人有会提出疑问,为什么我要先写M层嘛,我先C层或者V层不好么?
答
我的回答是先写哪个层都可以,只要你对这个MVC的设计模式你很清楚。那为什么这么说,因为当你很熟悉MVC的设计模式的时候,你会很清楚的知道MVC三个层直接的调用,但是这个对于初学者来说就比较难理解,因为先写M层有个好处是,之前对M层简单的介绍:M层主要是对业务逻辑的处理,数据库、网络、算法等。
简单的说就是:按照我们大脑的惯性思维就是我们先要了解这个业务逻辑,然后再跟着业务逻辑来写代码就很顺理成章,那么M层的主要功能就和我们的大脑的思维方式相同
返回顶部看下MVC的经典图片,M层的职责是:
Module职责
Module层数据模型层,对业务逻辑的处理,数据库、网络、算法等。
/**这是一个Model**/public class Module{ //从服务器请求获取新闻列表数据 void getNewsData() {} //保存新闻列表到内存中 void saveCacheNews(Lis<NewsBean> dataList){ //从内存缓存获取数据 NewsBean getNewsCache() {} }
M层里面2个方法,每个方法上面都有注释相信大家都应该很清楚知道是做什么用的,比如getNewsData()方法就是向我们的服务器获取新闻列表的数据,以此类推。
这里我就只详细介绍Android MVP系列(一)中的第一个需求,就是服务器获取新闻列表数据,然后保存内存并显示更新UI,后面的需求就以此类推。
一句话总结
我M层,我就只是负责获取数据,对数据进行加工,逻辑处理等,其他的我一概不管
View层
我相信V层大家都是很熟悉的,V层主要做什么呢?
View层职责
1.呈现M层的数据
2.主动询问或者被动监听(例如:下拉刷新列表主动询问)
3.通知C层处理
4.接收C层,改变UI
按照上面所述的职责我们来设计一个View层:
V层也就是我们经常说的显示UI层,那么既然MVC的设计模式,是分层处理事务,那么View层就只做View的相关事宜,其他的事情我不用关心。
//当列表初始化后,告诉控制器该加载数据了 void viewInit(){ controller.loadNewsList();} /**更新列表**/ void updateView() { //主动请求Model获取数据 NewsBean data = module.getNewsCache(); //更新 uilist.update(data); //隐藏loading界面 this.hideLoading() } //显示loading void showLoading(){ list.showLoading(); } //加载好数据后隐藏 loading void hideLoading() { list.hideLoading(); } }
我们可以很清楚的看到上面View层是持有Module和Controller两个类的对象,module是Module类的对象,controller是Controller的对象,那么怎么初始化这个我们暂时不用去理会,之后会统一的说明。这里可以能有一个疑问的地方就是updateView()方法里面有module.getNewsCache()方法。
问
有人可能会疑惑,这个module.getNewsCache()是什么时候去调用?我们怎么知道Module类里面的方法getNewsData()方法已经请求完数据,而且已经写入内存Cache中了?
答
这个问题就是精华所在,这个就是需要另一个层Controller层去处理的了,我们之前说了C层就是去控制V层更新UI,让Module层去服务端请求数据,所以这个问题我们放在C层的讲解的时候再细说
在写V层的职责的时候可能前三点都还好理解,但是第四点可能不是特别的理解。这里我详细解释一下:
4.接收C层,改变UI
我们在加载数据之前一般都有个动画,那么这个动画就是loading,也就是我们V层方法中的showLoading(),这个方法只和C层通信和M层没有关系,只是一个状态的改变,数据请求到与否有关系,所以这里的showLoading()方法我会在C层的介绍。
Controller层
最后我们来看看C层的职责是什么?
Controller层职责
接收V层的操控,并转调给M层来改变V层UI或者状态
/**这是一个Contorller**/public class Controller { void loadNewsList() { if(module.getNewsCache() == null){ //执行Modle module.getNewsData(); //执行View view.showLoading(); } } }
在C层我们可以看出来,C层是持有Module的类的对象module,V层的对象view,那么怎么初始化我们这章节也不介绍,后面会统一介绍。
我们可以先来解释一下前面所提到要才C层的时候来解释的问题:
1V层该什么时候去调用M层的getNewsCache方法?
这个问题是在V层初始化viewInit()方法的时候,C层调用了loadNewsList()方法的时候,转调给M层去调用getNewsData(),M层获取到数据保存到内存中之后就会调用V层的updateView()方法,以此来刷新界面数据。
2V层为什么不直接去M层调用网络请求新闻列表数据?
就这个问题是很好的,直接V层调用M层的网络请求不是更加直接,而且代码量也少不是很好吗?
这个好不好就不是说代码量少的问题,那就要从MVC这个框架来说起了,C层的作用就是接收V层的控制,转调M层请求数据,这样V层的职责就很清晰,而且C层的作用也体现出来了。
在这里功能比较少的时候,确实显得V层直接调用M层更加的清晰,但是当一个界面的功能越来越多的时候,你这样就会逻辑混乱,代码可读性差。
总结
我们可以很清楚的看到,M层 ,V层,C层他们的分工是非常明确的,各自做各自的事情,这样写出来的代码更加层次分明,逻辑清晰。这一章节主要是把M、V、C分成3个片段,那么怎么将这3个片段组织起来,那就我们在下一章节中见。
PS:如果想学习更多关于MVP,不管你之前了解过MVP,还是没有我都从最基础的讲解,如果觉得我讲的有用,私聊我,把前面章节,后面的都发给您。