【Android学习】两种MVP模式的学习(一):谷歌例子的简单学习

关于MVP的介绍网上有很多,身为搬运工的我直接搬来百度百科的,其实想来大家也都知道的。

MVP:
mvp的全称为Model-View-Presenter,Model提供数据,View负责显示,Controller/Presenter负责逻辑的处理。
MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Controller)来进行的,所有的交
互都发生在Presenter内部,而在MVC中View会直接从Model中读取数据而不是通过 Controller。

在学习MVP模式的时候,最近比较火的是谷歌的例子:
https://github.com/googlesamples/android-architecture
结构很清晰,用一个契约类将View,Presenter的接口写在里面,这样可以清晰的知道有哪些功能,界面有哪些会有变化,数据有哪些需要处理。

在Presenter创建时传入到View,同时将自身注入到View中,甚是巧妙。

来看一个小李子:



这是我模仿 掌上英雄联盟做的界面 ,除去 ViewPager中的内容,这个界面有两个地方需要获取数据。
一、轮播图。
二、Tab标签以及 “赛事”和“视频” 这俩悬浮页。
根据Fiddler听到的数据来看 ,轮播图是一个请求,Tab和悬浮页是一个请求。

所以基本步骤就是 ,定义设计Model,BaseView ,BasePresenter。

这里的Model比较简单,看一下就过去了:
model接口:

public interface LoLItemModel {  
  
    Observable<LoLBean> getLoLNewsData(String id, int page, String plat, int version);  
  
    Observable<LoLBean> getLoLBanner( String plat, int version);  
  
    Observable<List<LoLTypeBean>> getLoLType(String plat, int version);  
}  

model实现类:

public class LoLItemModelImpl implements LoLItemModel {  
    @Override  
    public Observable<LoLBean> getLoLNewsData(String id, int page,String plat, int version) {  
        LoLService service = NetWork.getInstance().create(LoLService.class);  
        return service.getNewsLoL(id, page, plat, version);  
    }  
  
    @Override  
    public Observable<LoLBean> getLoLBanner(String plat, int version) {  
        LoLService service = NetWork.getInstance().create(LoLService.class);  
        return service.getLoLBanner(plat, version);  
    }  
  
    @Override  
    public Observable<List<LoLTypeBean>> getLoLType(String plat, int version) {  
        LoLService service = NetWork.getInstance().create(LoLService.class);  
        return service.getLoLType(plat, version);  
    }  
}  

Model 是在Presenter中进行实例化操作的。

接着来看BaseView,BasePresenter:

public interface IBaseView<T> {
 void setPresenter(T presenter);
}
public interface IBasePresenter { 
                       void start(); 
                       void destroy();
}

BasePresenter里面的方法看实际而定,我可能需要初始化一些东西,定义了start(),因为使用RxJava,要考虑生命周期,所以定义一个destroy,在View结束时解绑。
然后就是契约类,这个界面 需要和数据进行交互的 只有设置轮播图,tab页。
所以就暂时先定下两个方法。

public class LoLMainContract {  
  
    public interface View extends IBaseView<Presenter> {  
        void initBanner(List<LoLBean.ListBean> bannerUrls);  
        void initTabs(List<LoLTypeBean> listbean);  
    }  
  
  
    public interface Presenter extends IBasePresenter {  
        void getBannersData();  
        void getTabsData();  
    }  
}  

实现Presenter:
在构造函数中 获取View同时将自身传入 View中。

public class LoLMainPresenter implements LoLMainContract.Presenter {  
    private LoLMainContract.View mView;  
    LoLItemModelImpl lolIml;  
    Subscription getBannerSPN;  
    Subscription getTabSPN;  
  
    public LoLMainPresenter(LoLMainContract.View mView) {  
        this.mView = mView;  
        this.mView.setPresenter(this);  
        lolIml = new LoLItemModelImpl();  
    }  
  
    @Override  
    public void getBannersData() {  
        getBannerSPN = RxManager.getInstance().doSubscribe(lolIml.getLoLBanner("android", 9705), new Subscriber<LoLBean>() {  
            @Override  
            public void onCompleted() {  
  
            }  
  
            @Override  
            public void onError(Throwable e) {  
  
            }  
  
            @Override  
            public void onNext(LoLBean loLTypeBeen) {  
  
                mView.initBanner(loLTypeBeen.getList());  
            }  
        });  
  
    }  
  
    @Override  
    public void getTabsData() {  
        getTabSPN = RxManager.getInstance().doSubscribe(lolIml.getLoLType("android", 9705), new Subscriber<List<LoLTypeBean>>() {  
            @Override  
            public void onCompleted() {  
  
            }  
  
            @Override  
            public void onError(Throwable e) {  
  
            }  
  
            @Override  
            public void onNext(List<LoLTypeBean> loLTypeBeen) {  
                mView.initTabs(loLTypeBeen);  
            }  
        });  
    }  
  
    @Override  
    public void start() {  
    }  
  
    @Override  
    public void destroy() {  
        if (getBannerSPN != null)  
            getBannerSPN.unsubscribe();  
        if (getTabSPN != null)  
            getTabSPN.unsubscribe();  
    }  
}  

在View生命周期结束的时候对观察者解绑。
然后就是实现View。
这里是Fragment 做View ,Activity统筹管理View

public class LoLMainFragment extends BaseFragment implements LoLMainContract.View{  }

我们的fragment实现契约类中Presenter的View接口,
声明Presenter并在实现View的方法中赋值:

private LoLMainContract.Presenter mPresenter;  
  
   @Override  
   public void setPresenter(LoLMainContract.Presenter presenter) {  
       this.mPresenter = presenter;  
   }  

获取数据 :

mPresenter.getBannersData();  
mPresenter.getTabsData();  

获取之后会调用View的方法 将返回的数据 在View中显示。

都实现之后就是 将V,P实例出来。
可以将方法放到 Fragment的 create中 。最好封装起来

new LoLMainPresenter(this);  

这样一个基本的MVP模式就出来了。
这只是练手用的,熟悉MVP构建方法流程。但是我们不能为了架构了使用架构,视具体情况而定。
页面功能多,逻辑复杂,那就得好好思量思量要怎么去实现能让层次清晰,维护方便。
总之,开心就好。

最近学到的还有一种MVP实现方式,挺好的,下篇来学习。
Mosby:https://github.com/sockeqwe/mosby

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,569评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,499评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,271评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,087评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,474评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,670评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,911评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,636评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,397评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,607评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,093评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,418评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,074评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,092评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,865评论 0 196
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,726评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,627评论 2 270

推荐阅读更多精彩内容