MVP框架之双向代理设计

阅读这篇文章需要掌握的知识代理模式

在上篇文章中我们实现了一个简单的Mvp模式初识MVP模式,通过中介者模式在MvpBasePresenter中关联M和V,以达到M和V的解耦。而这篇文章是在原来的基础,通过加入双向代理设计使代码结构更加清晰,但也更为复杂难懂。
何为双向代理

  1. 代理生命周期
  2. 代理P层

第一重代理:Activity生命周期的代理

通常情况下,MVP模式中Activity的onCreate和onDestroy分别会做P的创建、view的attachView和detachView的操作,但此时通过实现一层代理,通过代理生命周期(目标接口——目标对象——代理对象),把具体这些操作在我们自己实现的目标对象中完成,而Activity只需通过代理目标对象即可。这样也使得Activity中的代码被抽取出来,真正需要关心的是目标对象的内容。虽然这里只是把P的创建、view的绑定和解绑举例子,可能并不觉得这层代理的必要性,但以后如过要对P层缓存和View缓存做一系列的操作,所有的代码都写在Activity或则Fragment中这样就会是其代码显得很臃肿不清晰,换而言之在自己实现的目标对象中完成这些功能,而Activity或Fragment只需实现对目标对象的代理,这样也使得整体框架代码的结构更清晰明了、功能更单一,也更符合代码设计的原则。说了这么多接下来就来看看实现吧:

第一步:代理Activity的生命周期,先实现一个目标接口(onCreate、onRestoreInstanceState、onStart、onResume、onPause、onSaveInstanceState、onStop、onDestroy)

//第一重代理——》生命周期(目标接口)
public interface ActivityMvpDelegate <V extends MvpView,P extends MvpPresenter<V>>{
    void onCreate(Bundle savedInstanceState);

    void onRestoreInstanceState(Bundle savedInstanceState);

    void onStart();

    void onResume();

    void onPause();

    void onSaveInstanceState(Bundle outState);

    void onStop();

    void onDestroy();
}

第二步:实现目标对象ActivityMvpDelegateImpl,并目标对象实现目标接口ActivityMvpDelegate

// 第一重代理——》生命周期(目标对象——实现目标接口)
public class ActivityMvpDelegateImpl<V extends MvpView, P extends MvpPresenter<V>> implements ActivityMvpDelegate<V, P> {

    @Override public void onCreate(Bundle savedInstanceState) {
    }

    @Override public void onRestoreInstanceState(Bundle savedInstanceState) {
    }

    @Override public void onStart() {
    }

    @Override public void onResume() {
    }

    @Override public void onPause() {
    }

    @Override public void onSaveInstanceState(Bundle outState) {
    }

    @Override public void onStop() {
    }

    @Override public void onDestroy() {
    }
}

第三步:Activity就是生命周期的代理对象,在代理对象中有个重要的特性就是持有目标对象的引用,在Activity的生命周期方法中,分别代理目标对象ActivityMvpDelegateImpl对应的方法。

//第一重代理——》生命周期代理(代理对象——持有目标对象)
public abstract class MvpActivity<V extends MvpView, P extends MvpPresenter<V>> extends AppCompatActivity implements MvpVie{

    private ActivityMvpDelegate<V, P>   mvpDelegate;

    private ActivityMvpDelegate<V, P> getMvpDelegate() {
        if (mvpDelegate == null) {
            mvpDelegate = new ActivityMvpDelegateImpl<V, P>(this);
        }
        return mvpDelegate;
    }

    @Override protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getMvpDelegate().onCreate(savedInstanceState);

    }

    @Override protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        getMvpDelegate().onRestoreInstanceState(savedInstanceState);
    }

    @Override protected void onStart() {
        super.onStart();
        getMvpDelegate().onStart();
    }

    @Override protected void onResume() {
        super.onResume();
        getMvpDelegate().onResume();
    }

    @Override protected void onPause() {
        super.onPause();
        getMvpDelegate().onPause();
    }

    @Override protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        getMvpDelegate().onSaveInstanceState(outState);

    }

    @Override protected void onStop() {
        super.onStop();
        getMvpDelegate().onStop();
    }

    @Override protected void onDestroy() {
        super.onDestroy();
        getMvpDelegate().onDestroy();
    }
}

通过以上三步就实现了对Activity生命周期的代理,但是在目标对象ActivityMvpDelegateImpl还没有做具体的操作。那接下来要做的就是对P层的创建和View的绑定和解绑,也就是P层的代理。

第二重代理:P层代理

同样也需要三步(目标接口——目标对象——代理对象)

第一步:实现MvpDelegateCallback

//第二重代理——》P层的代理(目标接口)
public interface MvpDelegateCallback<V extends MvpView, P extends MvpPresenter<V>> {

    P createPresenter();

    P getPresenter();

    void setPresenter(P presenter);

    V getMvpView();

}

第二步:实现目标对象,而这里的目标对象是MvpActivity,并实现目标接口MvpDelegateCallback,这时MvpAvtivity中的代码如下

//第一重代理——》生命周期代理(代理对象——持有目标对象)
//第二重代理——》P层代理(目标对象——实现目标接口)
public abstract class MvpActivity<V extends MvpView, P extends MvpPresenter<V>> extends AppCompatActivity implements MvpView, MvpDelegateCallback<V, P> {

    private P                           presenter;

    private ActivityMvpDelegate<V, P>   mvpDelegate;

    private ActivityMvpDelegate<V, P> getMvpDelegate() {
        if (mvpDelegate == null) {
            mvpDelegate = new ActivityMvpDelegateImpl<V, P>();
        }
        return mvpDelegate;
    }

    /* ===============第二重代理================= */
    @Override public P createPresenter() {
        return presenter;
    }

    @Override public P getPresenter() {
        return presenter;
    }

    @Override public void setPresenter(P presenter) {
        this.presenter = presenter;
    }

    @Override public V getMvpView() {
        return (V) this;
    }

    @Override protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getMvpDelegate().onCreate(savedInstanceState);

    }

    @Override protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        getMvpDelegate().onRestoreInstanceState(savedInstanceState);
    }

    @Override protected void onStart() {
        super.onStart();
        getMvpDelegate().onStart();
    }

    @Override protected void onResume() {
        super.onResume();
        getMvpDelegate().onResume();
    }

    @Override protected void onPause() {
        super.onPause();
        getMvpDelegate().onPause();
    }

    @Override protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        getMvpDelegate().onSaveInstanceState(outState);

    }

    @Override protected void onStop() {
        super.onStop();
        getMvpDelegate().onStop();
    }

    @Override protected void onDestroy() {
        super.onDestroy();
        getMvpDelegate().onDestroy();
    }
}

第三步:实现代理P层的代理对象ProxyMvpDelegateCallback,根据代理对象的特性,持有目标对象的引用、实现目标接口(并不是必须的),代码如下:

// 第二重代理——》P层代理(代理对象——持有目标对象,实现目标接口)
public class ProxyMvpDelegateCallback<V extends MvpView, P extends MvpPresenter<V>> implements MvpDelegateCallback<V, P> {

    // 持有目标对象的引用,————————实际上就是MvpActivity
    private MvpDelegateCallback<V, P> mvpCallback;

    public ProxyMvpDelegateCallback(MvpDelegateCallback<V, P> mvpCallback) {
        this.mvpCallback = mvpCallback;
    }

    @Override public P createPresenter() {
        P presenter = this.mvpCallback.getPresenter();
        if (presenter == null) {
            presenter = this.mvpCallback.createPresenter();
        }
        if (presenter == null) {
            throw new NullPointerException("P层不能为空");
        }
        this.setPresenter(presenter);
        return presenter;
    }

    @Override public P getPresenter() {
        return this.mvpCallback.getPresenter();
    }

    @Override public void setPresenter(P presenter) {
        this.mvpCallback.setPresenter(presenter);
    }

    @Override public V getMvpView() {
        return this.mvpCallback.getMvpView();
    }

    /* ===============添加两个重要的方法——绑定和解绑================= */
    public void attachView() {
        getPresenter().attachView(getMvpView());
    }

    public void detachView() {
        getPresenter().detachView();
    }
}

双重代理的关联

通过以上三步,已经实现了对P层的代理。但是有没有发现,虽然实现对P层的代理但P层的创建以及View的绑定和解绑并没有与Activity的生命周期关联起来。还记得在实现代理生命周期的时候说的 ,虽然实现了对生命周期的代理,但在目标对象ActivityMvpDelegateImpl中并没有做具体的操作。也就是说我们需要在ActivityMvpDelegateImpl做关联双向代理的的操作,如P层的创建、view的绑定与解绑。

在ActivityMvpDelegateImpl类中在其构造方法中创建ProxyMvpDelegateCallback代理对象,在onCreate调用ProxyMvpDelegateCallback的createPresenter、attachView方法,在onDestroy中调用ProxyMvpDelegateCallback的detachView,ActivityMvpDelegateImpl最终代码如下:

// 第一重代理——》生命周期(目标对象——实现目标接口)
public class ActivityMvpDelegateImpl<V extends MvpView, P extends MvpPresenter<V>> implements ActivityMvpDelegate<V, P> {

    private ProxyMvpDelegateCallback<V, P> mvpCallback;

    //双重代理的关联
    public ActivityMvpDelegateImpl(MvpDelegateCallback<V, P> mvpDelegateCallback) {
        mvpCallback = new ProxyMvpDelegateCallback<V, P>(mvpDelegateCallback);
    }

    @Override public void onCreate(Bundle savedInstanceState) {
        mvpCallback.createPresenter();
        mvpCallback.attachView();

    }

    @Override public void onRestoreInstanceState(Bundle savedInstanceState) {

    }

    @Override public void onStart() {

    }

    @Override public void onResume() {

    }

    @Override public void onPause() {

    }

    @Override public void onSaveInstanceState(Bundle outState) {

    }

    @Override public void onStop() {

    }

    @Override public void onDestroy() {
        mvpCallback.detachView();

    }
}

还需要把MvpActivity创建ActivityMvpDelegateImpl方法改为如下代码:

private ActivityMvpDelegate<V, P> getMvpDelegate() {
    if (mvpDelegate == null) {
        mvpDelegate = new ActivityMvpDelegateImpl<V, P>(this);
    }
    return mvpDelegate;
}

到这里双向代理设计已经全部完了,最后把整篇文章做个总结,对其内容实现梳理:

  • MvpActivity在生命周期的代理中扮演代理对象的角色,当一个Activity创建时会执行onCreate,因其代理对象角色,会执行被代理对象(目标对象)的方法,在这里也就是ActivityMvpDelegateImpl的onCreate方法
    @Override public void onCreate(Bundle savedInstanceState) {
        this.proxyMvpCallback.createPresenter();
        this.proxyMvpCallback. attachView();
    }
  • 在ActivityMvpDelegateImpl中因为其关联了P层代理的代理对象ProxyMvpDelegateCallback,并执行其createPresenter和attachView,又因其是代理对象的原因,最终执行的是被代理的目标对象Activity的createPresenter,所以这里MvpActivity在P层代理时其角色又是目标对象。

关于MvpFragment双向代理的实现就不再介绍,内容和Activity的实现基本上是一致的。最后贴上源码地址github,里面有MvpFragment实现代码。同时也欢迎大家拍砖提供宝贵意见,共同进步。


风后面是风,天空上面是天空,而你的生活可以与众不同

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

推荐阅读更多精彩内容