你们的魔鬼又来咯!Android-App的设计架构:MVC,MVP,MVVM与架构经验谈(1)
至于这里为什么不直接设计成类里面的一个getWeather()方法直接请求网络数据?你考虑下这种情况:现在代码中的网络请求是使用Volley框架来实现的,如果哪天老板非要你使用Afinal框架实现网络请求,你怎么解决题目?岂非是修改 getWeather()方法的实现? no no no,这样修改不仅破坏了从前的代码,而且还不利于维护, 考虑到以后代码的扩展和维护性,我们选择设计接口的方式来解决着一个题目,我们实现另外一个WeatherModelWithAfinalImpl类,继承自WeatherModel,重写里面的方法,这样不仅保留了从前的WeatherModelImpl类请求网络方式,还增长了WeatherModelWithAfinalImpl类的请求方式。Activity调用代码无必要任何修改。3.MVP设计架构
在App开发过程中,经常出现的题目就是某一部分的代码量过大,虽然做了模块分别和接口隔离,但也很难完全制止。从实践中看到,这更多的出现在UI部分,也就是Activity里。想象一下,一个2000+行以上基本不带解释的Activity,我的第一反应就是想吐。Activity内容过多的原因实在很好解释,因为Activity自己必要担负与用户之间的操纵交互,界面的展示,不是单纯的Controller或View。而且现在大部分的Activity还对整个App起到类似IOS中的【ViewController】的作用,这又带入了大量的逻辑代码,造成Activity的痴肥。为了解决这个题目,让我们引入MVP框架。
MVC的缺点
在Android开发中,Activity并不是一个标准的MVC模式中的Controller,它的首要职责是加载应用的结构和初始化用户 界面,并接受并处理来自用户的操纵请求,进而作出响应。随着界面及其逻辑的复杂度不停提升,Activity类的职责不停增长,以致变得巨大痴肥。
什么是MVP?
MVP从更早的MVC框架演变过来,与MVC有一定的相似性:Controller/Presenter负责逻辑的处理,Model提供数据,View负责表现。
https://i-blog.csdnimg.cn/blog_migrate/b5237a3b3942d9565e0eac404b985d55.png
MVP框架由3部分构成:View负责表现,Presenter负责逻辑处理,Model提供数据。在MVP模式里通常包含3个要素(加上View interface是4个):
[*] View:负责绘制UI元素、与用户举行交互(在Android中表现为Activity)
[*] Model:负责存储、检索、操纵数据(有时也实现一个Model interface用来降低耦合)
[*] Presenter:作为View与Model交互的中间纽带,处理与用户交互的负责逻辑。
[*] *View interface:必要View实现的接口,View通过View interface与Presenter举行交互,降低耦合,方便举行单元测试
*Tips:View interface的必要性
回想一下你在开发Android应用时是如何对代码逻辑举行单元测试的?是否每次都要将应用摆设到Android模仿器或真机上,然后通过模仿用 户操纵举行测试?然而由于Android平台的特性,每次摆设都耗费了大量的时间,这直接导致开发服从的降低。而在MVP模式中,处理复杂逻辑的Presenter是通过interface与View(Activity)举行交互的,这说明我们可以通过自定义类实现这个interface来模仿Activity的举动对Presenter举行单元测试,省去了大量的摆设及测试的时间。
MVC → MVP
当我们将Activity复杂的逻辑处理移至另外的一个类(Presenter)中时,Activity实在就是MVP模式中的View,它负责UI元素的初始化,创建UI元素与Presenter的关联(Listener之类),同时自己也会处理一些简单的逻辑(复杂的逻辑交由 Presenter处理)。
MVP的Presenter是框架的控制者,负担了大量的逻辑操纵,而MVC的Controller更多时间负担一种转发的作用。因此在App中引入MVP的原因,是为了将此前在Activty中包含的大量逻辑操纵放到控制层中,制止Activity的痴肥。
两种模式的重要区别:
[*](最重要区别)View与Model并不直接交互,而是通过与Presenter交互来与Model间接交互。而在MVC中View可以与Model直接交互
[*]通常View与Presenter是一对一的,但复杂的View可能绑定多个Presenter来处理逻辑。而Controller是基于举动的,而且可以被多个View共享,Controller可以负责决定表现哪个View
[*]Presenter与View的交互是通过接口来举行的,更有利于添加单元测试。
https://i-blog.csdnimg.cn/blog_migrate/f9c935d2414906e5ec2aa922cf6b877a.png
因此我们可以发现MVP的优点如下:
1、模型与视图完全分离,我们可以修改视图而不影响模型;
2、可以更高效地使用模型,因为全部的交互都发生在一个地方——Presenter内部;
3、我们可以将一个Presenter用于多个视图,而不必要改变Presenter的逻辑。这个特性非常的有用,因为视图的变革总是比模型的变革频繁;
4、如果我们把逻辑放在Presenter中,那么我们就可以脱离用户接口来测试这些逻辑(单元测试)。
具体到Android App中,一样平常可以将App根据程序的结构举行纵向分别,根据MVP可以将App分别为模型层(M),UI层(V)和逻辑层§。
UI层一样平常包括Activity,Fragment,Adapter等直接和UI相关的类,UI层的Activity在启动之后实例化相应的Presenter,App的控制权后移,由UI转移到Presenter,两者之间的通信通过BroadCast、Handler大概接口完成,只通报事故和结果。
举个简单的例子,UI层关照逻辑层(Presenter)用户点击了一个Button,逻辑层(Presenter)自己决定应该用什么举动举行响应,该找哪个模型(Model)去做这件事,最后逻辑层(Presenter)将完成的结果更新到UI层。
##MVP的变种:Passive View
MVP的变种有许多,其中使用最广泛的是Passive View模式,即被动视图。在这种模式下,View和Model之间不能直接交互,View通过Presenter与Model打交道。Presenter接受View的UI请求,完成简单的UI处理逻辑,并调用Model举行业务处理,并调用View将相应的结果反映出来。View直接依赖Presenter,但是Presenter间接依赖View,它直接依赖的是View实现的接口。
https://i-blog.csdnimg.cn/blog_migrate/8fa3ac635566de37fc64a6c90d69e83e.png
相对于View的被动,那Presenter就是自动的一方。对于Presenter的自动,有如下的明白:
[*]Presenter是整个MVP体系的控制中心,而不是单纯的处理View请求的人;
[*]View仅仅是用户交互请求的汇报者,对于响应用户交互相关的逻辑和流程,View不参与决策,真正的决策者是Presenter;
[*]View向Presenter发送用户交互请求应该采用这样的口吻:“我现在将用户交互请求发送给你,你看着办,必要我的时间我会帮忙你”,不应该是这样:“我现在处理用户交互请求了,我知道该怎么办,但是我必要你的支持,因为实现业务逻辑的Model只信任你”;
[*]对于绑定到View上的数据,不应该是View从Presenter上“拉”回来的,应该是Presenter自动“推”给View的;
[*]View尽可能不维护数据状态,因为其自己仅仅实现单纯的、独立的UI操纵;Presenter才是整个体系的调和者,它根据处理用于交互的逻辑给View和Model安排工作。
MVP架构存在的题目与解决办法
[*]加入模板方法(Template Method)
转移逻辑操纵之后可能部分较为复杂的Activity内代码量还是不少,于是必要在分层的基础上再加入模板方法(Template Method)。
具体做法是在Activity内部分层。其中最顶层为BaseActivity,不做具体表现,而是提供一些基础样式,Dialog,ActionBar在内的内容,展现给用户的Activity继承BaseActivity,重写BaseActivity预留的方法。如有必要再举行二次继承,App中Activity之间的继承次数最多不凌驾3次。
[*]Model内部分层
模型层(Model)中的团体代码量是最大的,一样平常由大量的Package构成,针对这部分必要做的就是在程序设计的过程中,做好模块的分别,举行接口隔离,在内部举行分层。
[*]强化Presenter
强化Presenter的作用,将全部逻辑操纵都放在Presenter内也容易造成Presenter内的代码量过大,对于这点,有一个方法是在UI层和Presenter之间设置中介者Mediator,将比方数据校验、组装在内的轻量级逻辑操纵放在Mediator中;在Presenter和Model之间使用代理Proxy;通过上述两者分担一部分Presenter的逻辑操纵,但团体框架的控制权还是在Presenter手中。Mediator和Proxy不是必须的,只在Presenter负担过大时才发起使用。
终极的架构如下图所示:
https://i-blog.csdnimg.cn/blog_migrate/676b3da1d6837537987636f66056f162.png
MVP代码实例
我们来看看MVP在Android开发中是怎么应用的吧!!
我们用另一个例子来解释。
先来看包结构图
https://i-blog.csdnimg.cn/blog_migrate/2bfd6118f839a10bcfcb3cccfdef6cfc.png
创建Bean
public class UserBean {
private String mFirstName;
private String mLastName;
public UserBean(String firstName, String lastName) {
this. mFirstName = firstName;
this. mLastName = lastName;
}
public String getFirstName() {
return mFirstName;
}
public String getLastName() {
return mLastName;
}
}
创建Model
(处理业务逻辑,这里指数据读写),先写接口,后写实现
public interface IUserModel {
void setID(int id);
void setFirstName(String firstName);
void setLastName(String lastName);
int getID();
UserBean load(int id);// 通过id读取user信息,返回一个UserBean
}
实现不在这里写了
Presenter控制器
创建presenter(主导器,通过iView和iModel接口操纵model和view),activity可以把全部逻辑给presenter处理,这样java逻辑就从手机的activity中分离出来。
public class UserPresenter {
private IUserView mUserView;
private IUserModel mUserModel;
public UserPresenter(IUserView view) {
mUserView = view;
mUserModel = new UserModel();
}
public void saveUser( int id, String firstName, String lastName) {
mUserModel.setID(id);
mUserModel.setFirstName(firstName);
mUserModel.setLastName(lastName);
}
public void loadUser( int id) {
UserBean user = mUserModel.load(id);
mUserView.setFirstName(user.getFirstName()); // 通过调用IUserView的方法来更新表现
mUserView.setLastName(user.getLastName());
}
}
View视图
创建view(更新ui中的view状态),这里列出必要操纵当前view的方法,也是接口
public interface IUserView {
int getID();
String getFristName();
String getLastName();
void setFirstName(String firstName);
void setLastName(String lastName);
}
activity中实现iview接口,在其中操纵view,实例化一个presenter变量。
public class MainActivity extends Activity implements OnClickListener,IUserView {
UserPresenter presenter;
EditText id,first,last;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout. activity_main);
findViewById(R.id. save).setOnClickListener( this);
findViewById(R.id. load).setOnClickListener( this);
id = (EditText) findViewById(R.id. id);
first = (EditText) findViewById(R.id. first);
last = (EditText) findViewById(R.id. last);
presenter = new UserPresenter( this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id. save:
presenter.saveUser(getID(), getFristName(), getLastName());
break;
case R.id. load:
presenter.loadUser(getID());
break;
default:
break;
}
}
@Override
public int getID() {
return new Integer( id.getText().toString());
}
@Override
public String getFristName() {
return first.getText().toString();
}
@Override
public String getLastName() {
return last.getText().toString();
}
@Override
public void setFirstName(String firstName) {
first.setText(firstName);
}
@Override
public void setLastName(String lastName) {
last.setText(lastName);
}
}
因此,Activity及从MVC中的Controller中解放出来了,这会Activity重要做表现View的作用和用户交互。每个Activity可以根据自己表现View的不同实现View视图接口IUserView。
通过对比同一实例的MVC与MVP的代码,可以证实MVP模式的一些优点:
[*]在MVP中,Activity的代码不痴肥;
[*]在MVP中,Model(IUserModel的实现类)的改动不会影响Activity(View),两者也互不干涉,而在MVC中会;
[*]在MVP中,IUserView这个接口可以实现方便地对Presenter的测试;
[*]在MVP中,UserPresenter可以用于多个视图,但是在MVC中的Activity就不行。
4.MVC、MVP与MVVM的关系
首先先容下MVVM。
MVVM
MVVM可以算是MVP的升级版,其中的VM是ViewModel的缩写,ViewModel可以明白成是View的数据模型和Presenter的合体,ViewModel和View之间的交互通过Data Binding完成,而Data Binding可以实现双向的交互,这就使得视图和控制层之间的耦合程度进一步降低,关注点分离更为彻底,同时减轻了Activity的压力。
在比较之前,先从图上看看三者的异同。
https://i-blog.csdnimg.cn/blog_migrate/fb4315cb7ce7ac6e5ccb7a608f2a5970.png
刚开始明白这些概念的时间认为这几种模式虽然都是要将view和model解耦,但黑白此即彼,没有关系,一个应用只会用一种模式。厥后慢慢发现世界绝对不是只有黑白两面,中间最大的一块实在是灰色地带,同样,这几种模式的界限并非那么显着,可能你在自己的应用中都会用到。现实上也根本没必要去纠结自己到底用的是MVC、MVP还是MVVP,不管黑猫白猫,捉住老鼠就是好猫。
MVC->MVP->MVVM演进过程
MVC -> MVP -> MVVM 这几个软件设计模式是一步步演化发展的,MVVM 是从 MVP 的进一步发展与规范,MVP 隔离了MVC中的 M 与 V 的直接接洽后,靠 Presenter 来中转,所以使用 MVP 时 P 是直接调用 View 的接口来实现对视图的操纵的,这个 View 接口的东西一样平常来说是 showData、showLoading等等。M 与 V已经隔离了,方便测试了,但代码还不够优雅简便,所以 MVVM 就弥补了这些缺陷。在 MVVM 中就出现的 Data Binding 这个概念,意思就是 View 接口的 showData 这些实现方法可以不写了,通过 Binding 来实现。
同
如果把这三者放在一起比较,先说一下三者的共同点,也就是Model和View:
[*] Model:数据对象,同时,提供本应用外部对应用程序数据的操纵的接口,也可能在数据变革时发出变动关照。Model不依赖于View的实现,只要外部程序调用Model的接口就能够实现对数据的增编削查。
[*] View:UI层,提供对终极用户的交互操纵功能,包括UI展今世码及一些相关的界面逻辑代码。
异
三者的差别在于如何粘合View和Model,实现用户的交互操纵以及变动关照
[*]Controller
Controller吸收View的操纵事故,根据事故不同,大概调用Model的接口举行数据操纵,大概举行View的跳转,从而也意味着一个Controller可以对应多个View。Controller对View的实现不太关心,只会被动地吸收,Model的数据变动不通过Controller直接关照View,通常View采用观察者模式监听Model的变革。
[*]Presenter
自我先容一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Android工程师,想要提升技能,往往是自己探索发展大概是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此网络整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋侪,同时减轻大家的负担。
https://i-blog.csdnimg.cn/blog_migrate/2e5360381187cdeebcae2d31f2a8ee57.png
https://i-blog.csdnimg.cn/blog_migrate/3585ccdf6e545ec3b3fe922fcc5a676c.png
https://i-blog.csdnimg.cn/blog_migrate/664efd75f357a489fa3604edbddab0f6.png
https://i-blog.csdnimg.cn/blog_migrate/bc67557d29d1fb39e7b6cb95107c0a6b.png
https://i-blog.csdnimg.cn/blog_migrate/7b2861fab0b9f6e315c8d3f3cab04ba4.png
https://i-blog.csdnimg.cn/blog_migrate/04fd2ab11be6809d2d76fea33970af3b.png
https://i-blog.csdnimg.cn/blog_migrate/749668a5e5073806197273f66d7883b9.png
既有适合小白学习的零基础资料,也有适合3年以上经验的小同伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目次大纲截图出来,每个节点里面都包含大厂面经、学习条记、源码讲义、实战项目、解说视频,而且后续会持续更新
如果你以为这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
https://i-blog.csdnimg.cn/blog_migrate/e28fce02efe2dfd12b0d122300ad1475.png
最后我想说
为什么许多程序员做不了架构师?
1、良好健康的职业规划很重要,但大多数人都忽略了
2、学习的习惯很重要,持之以恒才是正解。
3、编程头脑没能提升一个台阶,范围在了编码,业务,没考虑过选型、扩展
4、身边没有好的架构师引导、培养。所处的圈子对程序员的发展影响巨大。
金九银十口试季,跳槽季,整理口试题已经成了我多年的习惯!在这里我和身边一些朋侪特意整理了一份快速进阶为Android高级工程师的系统且全面的学习资料。涵盖了Android初级——Android高级架构师进阶必备的一些学习技能。
附上:我们之前因为秋招网络的二十套一二线互联网公司Android口试真题(含BAT、小米、华为、美团、滴滴)和我自己整理Android复习条记(包含Android基础知识点、Android扩展知识点、Android源码剖析、设计模式汇总、Gradle知识点、常见算法题汇总。)
https://i-blog.csdnimg.cn/blog_migrate/18de9c3d0f152a6a3792287904d855ea.png
里面包含不同方向的自学编程路线、口试题聚集/面经、及系列技术文章等,资源持续更新中…
一个人可以走的很快,但一群人才华走的更远。不论你是正从事IT行业的老鸟或是对IT行业感爱好的新人,都欢迎扫码加入我们的的圈子(技术交换、学习资源、职场吐槽、大厂内推、口试辅导),让我们一起学习发展!
https://i-blog.csdnimg.cn/blog_migrate/92162b0bbcb2faba9529a76818f114ee.png
、小米、华为、美团、滴滴)和我自己整理Android复习条记(包含Android基础知识点、Android扩展知识点、Android源码剖析、设计模式汇总、Gradle知识点、常见算法题汇总。)
[外链图片转存中…(img-sTbfN1zu-1712808515887)]
里面包含不同方向的自学编程路线、口试题聚集/面经、及系列技术文章等,资源持续更新中…
一个人可以走的很快,但一群人才华走的更远。不论你是正从事IT行业的老鸟或是对IT行业感爱好的新人,都欢迎扫码加入我们的的圈子(技术交换、学习资源、职场吐槽、大厂内推、口试辅导),让我们一起学习发展!
[外链图片转存中…(img-Ir29ldC1-1712808515887)]
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]