下一篇文章:安卓 APP 架构模式:MVC MVP MVVM (代码讲解)
本篇主要介绍认识三种架构
目录
一、架构设计的目的
二、MVC架构
1、MVC组成
2、各部分之间的通信方式:
3、互动模式
4、实际项目
5、使用总结
三、MVP架构
1、MVP组成
2、MVC与MVP差别
3、view层和presenter层不是耦合在一起了吗?
四、MVVM架构
通过架构设计使程序模块化,可以让模块内部高内聚和模块之间低耦合。
好处:使得程序在开发过程中,开发人员只需要专注于一点,提高开发效率,并且更容易进行后续的测试及定位问题。
注意:设计不能违背目的,对于不同量级的工程,具体架构的实现方式必然是不同的,切忌犯为了设计而设计,为了架构而架构的毛病。
简单地说:复杂的软件必须有清晰合理的架构,否则无法开发和维护。
举例:
1、不使用架构:如果一个App只有3个Java文件,那只需要做模块和层次的划分就可以,引入框架或者架构反而提高了工作量,降低了生产力;
2、使用架构:当前开发的App最终代码量在10W行以上,本地需要进行复杂操作,同时也需要考虑到与其余的Android开发者以及后台开发人员之间的同步配合,那就需要在架构上进行一些思考!
MVC模式可以分成三个部分:
模型(Model): 数据保存
视图(View): 用户界面。
控制器(Controller): 业务逻辑
具体解释:
模型层(Model):
针对业务模型,建立的数据结构和相关的类,就可以理解为Model。
Model是与View无关,而与业务相关的。
对数据库的操作、对网络等的操作都应该在Model里面处理,当然对业务计算等操作也是必须放在的该层的。
视图层(View):
一般采用XML文件进行界面的描述,这些XML可以理解为View。
使用的时候可以非常方便的引入,同时便于后期界面的修改。
逻辑中与界面对应的id不变化则代码不用修改,大大增强了代码的可维护性。
控制层(Controller):
Android的控制层的重任通常落在了众多的Activity的肩上。
这句话暗含了不要在Activity中写代码,要通过Activity交割Model业务逻辑层处理。
这样做的原因是Android中的Activity的响应时间是5s,如果耗时的操作放在这里,程序容易出现问题。
工作原理:当用户出发事件的时候,view层会发送指令到controller层,接着controller去通知model层更新数据,model层更新完数据以后直接显示在view层上
1、View 传送指令到 Controller
2、Controller 完成业务逻辑后,要求 Model 改变状态
3、Model 将新的数据发送到 View,用户得到反馈
所有通信都是单向的。
一种是通过 View 接受指令,传递给 Controller。
一种是直接通过controller接受指令。
实际项目往往采用更灵活的方式
1. 用户可以向 View 发送指令(DOM 事件),再由 View 直接要求 Model 改变状态。
2. 用户可以直接向 Controller 发送指令(改变 URL 触发 hashChange 事件),再由 Controller 发送给 View。
在Android项目中,数据处理等担任Model(模型)角色,XML界面显示等担任View(视图)角色,Activity担任Contronller(控制器)角色。
contronller(控制器)是一个中间桥梁的作用,通过接口通信来协同 View(视图)和Model(模型)工作,起到了两者之间的通信作用。
当然一个小的项目且无需频繁修改需求就不用MVC框架来设计了,那样反而觉得代码过度设计,代码臃肿。
一般在大的项目中,且业务逻辑处理复杂,页面显示比较多,需要模块化设计的项目使用MVC就有足够的优势了。
在MVC模式控制器Activity主要是起到解耦作用,将View视图和Model模型分离。
虽然Activity起到交互作用,但是Activity中有很多关于视图UI的显示代码,因此View视图和Activity控制器并不是完全分离
的,即说一部分View视图和Contronller控制器Activity是绑定在一个类中的。
耦合性低:MVC框架使得View层和Model层可以分离,达到了解耦的目的,使耦合性低,减少模块代码之间的相互影响。
可扩展性好:由于耦合性低,添加需求,扩展代码就可以减少修改之前的代码,降低bug的出现率。
模块职责划分明确:主要划分层M,V,C三个模块,利于代码的维护。
举例:界面有一个按钮,按下这个按钮去网络上下载一个文件,
view层: 按钮是使用xml来写的
model层:和网络连接相关的代码写在一个专门的networkHelper类里
controller层:通过button.setOnClickListener()函数连接这两层,这个函数就写在了activity中。
问题:
1、问题就在于xml作为view层,控制能力实在太弱了,你想去动态的改变一个页面的背景,或者动态的隐藏/显示一个按钮,这些都没办法在xml中做,只能把代码写在activity中,造成了activity既是controller层,又是view层。
2、看下图,view层和model层是相互可知的,这意味着两层之间存在耦合,耦合对于一个大型程序来说是非常致命的,因为这表示开发,测试,维护都需要花大量的精力。
正因为MVC有这样那样的缺点,所以才演化出了MVP和MVVM这两种框架。
MVP 模式将 Controller 改名为 Presenter,同时改变了通信方向。
MVP的model层相对于MVC是一样的,而activity和fragment不再是controller层,而是纯粹的view层,所有关于用户事件的转发全部交由presenter层处理。
MVP模式中,view层和presenter层靠的是接口进行连接。
1. 各部分之间的通信,都是双向的。
2. View 与 Model 不发生联系,都通过 Presenter 传递。
3. View 非常薄,不部署任何业务逻辑,称为"被动视图"(Passive View),没有任何主动性。
4. 而 Presenter非常厚,所有逻辑都部署在那里。
执行过程:代码执行的一般顺序是从View层的某个事件被触发开始,View层不做任何处理,直接将这个事件所需要的数据一并传给Presenter,Presenter的特定事件被触发之后,经过一些分析判断,如果有必要的话,接着向对应的Model层请求数据,Model层经过对数据的增删改查等一系列操作之后,返回Presenter,Presenter再加工一下,最终在View层给用户一些反馈。
最明显的就是view层和model层不再相互可知,完全的解耦。
取而代之的presenter层充当了桥梁的作用,用于操作view层发出的事件传递到presenter层中,presenter层去操作model层,并且将数据返回给view层,整个过程中view层和model层完全没有联系。
对于view层和presenter层的通信,我们是可以通过接口实现的,
就是说我们的activity,fragment可以去实现实现定义好的接口,而在对应的presenter中通过接口调用方法。
不仅如此,我们还可以编写测试用的View,模拟用户的各种操作,从而实现对Presenter的测试。这就解决了MVC模式中测试,维护难的问题。
当然,其实最好的方式是使用fragment作为view层,而activity则是用于创建view层(fragment)和presenter层(presenter)的一个控制器。
MVVM 模式将 Presenter 改名为 ViewModel,基本上与 MVP 模式完全一致。
区别:双向绑定(data-binding view层和viewmodel层是相互绑定),View的变动,自动反映在 ViewModel,反之亦然。
Angular 和 Ember 都采用这种模式。
参考链接:
阮一峰老师
csdn贵公子博客
huhanghao