AndroidMVP开发模式-Contract用法

更新时间:2023-07-08 07:59:12 阅读: 评论:0

AndroidMVP开发模式-Contract⽤法
说起Android⽐较流⾏的架构模型,MVC、MVP、MVVM这⼏种是最常见的,也是当前主流的架构模型,本篇通过对MVC到MVP的进化过程,给出⼀种MVP个⼈认为⽐较适合的开发模式 - Contract⽤法:
MVP前世
MVC模式(Model、View、Controller)已经开始渐渐地退出,它最⼤的痛点在于Controller中既承载了View⼜包括了业务逻辑,导致Controller最终会很庞⼤,不利于维护和可读,⽐如:
publicclassXXXActivityextentsActivity{
publicvoidonCreate(Bundle saveInstanceState){
清凉饮品tContentView(layout);
initView();
initData();
}
publicvoidinitView(){
view1 = findViewById(id);
view2 = findViewById(id);
...
view1.tOnClickListener( this);
view2.tXXListener(..);
...
}
publicvoidinitData(){
model.loadData(respon -> {
view1.tXXX(respon.XX);
view2.tXXX(respon.XX);
});
...
}
@Override
publicvoidonClick(View v){
model.doSth();
...
}
}
即使你拆分出许多XXXHelper或者说XXXViewBlock,并且只在Controller中处理业务流程(Helper或者Block中持有Activity引⽤,不持有Model,为了不与Model耦合在⼀起),⽐如:publicclassXXXActivityextentsActivity{
privateXXViewHelper helper1;
privateXXViewHelper helper2;
publicvoidonCreate(Bundle saveInstanceState){
tContentView(layout);
initView();
initData();
}
publicvoidinitView(){
helper1 = newXXViewHelper( this); // 传⼊Activity
helper2 = newXXViewHelper( this); // 传⼊Activity
}
publicvoidinitData(){
model.loadData(respon -> {
helper1.updateView(respon);
helper2.updateView(respon);
});
...
...
}
// 供Helper调⽤
publicvoidcommit(){
}
// 供Helper调⽤
publicvoiddoSth(){
全民公决model.doSth();
}
}
但仍然解决不了的问题是,Activity向这些Helper或者Block暴露的信息太多了,⽐如⽣命周期这些⽅
法,以及不希望Helper它们看到的⽅法,不利于开发者对业务流程的理解,并且看到没有?现在的Activity已经有点像Prenter了,只是⾥边还存在⼀些 Helper的初始化。
MVP今⽣
由于上述分析,为了进⼀步减轻Activity的压⼒,所以决定将Activity只做⼀些与View相关的事情,那处理业务流程的部分去哪了?这个就是新产⽣的⼀个模块-Prenter。虽然很多⽂章都有写,但我还是再次声明下它们的⼯作职责,如下:
MVP⽰意图
View: 只处理UI及页⾯效果的细节,向Prenter暴露更新UI的⽅法;并且持有Prenter的引⽤,通过Prenter对其暴露的⽅法进⾏⼀些初始化页⾯以及业务提交等动作,但不关注动作的具体实现。
Prenter:只关注业务逻辑的细节,持有View的引⽤,通过调⽤View层向其暴露的⽅法去更新UI (这⾥的View引⽤不是具体某个控件的引⽤,我们也不能让Prenter持有某⼀控件的引⽤);并且也持有⼀个或者多个model的引⽤(在于你想将Prenter,也就是业务逻辑拆分的程度,避免Prenter也像MVC中Controller⼀样被撑爆),可以使⽤model,通过对数据库或者⽹络的访问从⽽拿到数据,调⽤View暴露的⽅法去刷新UI。
Model:向Prenter暴露获取、存储、提交数据等⽅法,具体实现细节Prenter不关注;Model通过Callback 将数据返回给Prenter。
Ok,按照之前规定的原则:
•View 向 Prenter 暴露更新UI的⽅法,于是我们有了 IView
•Prenter 向 View 暴露执⾏⼀些特定业务⽅法,⽐如初始化页⾯,提交等。
于是,就产⽣了第⼀种MVP模式:
MVP第⼀种模式
MVP第⼀种模式
看到以上类图,可能会有⼈有疑问:
1.在IView中为什么我不直接写 updateView(Respon r),这样不是写的接⼝⽅法更少吗?这个问题问的好!因为我
曾经也有过这样的问题,试想⼀下,如果我们把Model中的Respon直接存在于Activity(View层)中,
那当我们更改Respon的时候,会导致View层也需要进⾏相应的变动,还能做到View和Model的完全解耦吗?所以View 向Prenter暴露的⽅法参数⼀定要符合两点:(1). 基本数据类型(2). 公共数据类型
2.为什么要写IPrenter,让Activity直接引⽤ XXXPrenter不就好了?确实,这样做从功能上来说也可以,但是,为
了更严格⼀些,让Prenter向View暴露那些View关注的⽅法,这样开发View的同学就会⼀下⼦明⽩⾃⼰只需要关注哪些⽅法就够了;同理,Prenter持有IView的引⽤⽽不是Activity的也是这个原因。
按照以上模式,我们⽤伪代码来实现⼀下第⼀种MVP模式(以下代码不严谨,只表达意思):
Prenter:interfaceIPrenter{
voidinitData();
voidcommit();
}
classXXXPrenterimplementsIPrenter{
privateIView mView;
privateModel mModel;
privateCallback mCallback = newCallback() {
publicvoidonSuccess(Respon r){
mView.cancelLoading();
if(r.url == 'initDataUrl') {
mView.updateHeader(r.header);
mView.t);
} elif(r.url == 'commitUrl') {
// 页⾯跳转或者其他什么的
不客气的英语怎么说
}
}
认字游戏publicvoid(Error e){
mView.showError();
}
};
XXXPrenter(IView view) {
mView = view;
mModel = newModel();
}
@Override
publicvoidinitData(){
军训作文开头
知了龟
mView.showLoading();
两只老虎儿歌歌词
}
@Override
publicvoidcommit(){
mView.showLoading();
}
}
View:interfaceIView{春风吹啊吹
voidupdateHeader(String header);
voidupdateContent(String content);
voidshowLoading();
voidcancelLoading();
voidshowError(String error);
} publicclassXXXActivityextendsBaActivityimplementsIView{ privateIPrenter mPrenter;
privateTextView tvHeader;
privateTextView tvContent;
publicvoidonCreate(Bundle saveInstanceState){

本文发布于:2023-07-08 07:59:12,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/1072689.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:业务   逻辑   关注   业务流程   细节
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图