MVP应用架构模式

编辑于2017年3月24日

参考:《Android源码设计模式 解析与实战》一书


大致分包如下图

M:负责获取,存储,检索等操作数据,持有数据对象并直接对其进行操作。

V: View Interface:抽取UI及数据展示隐藏等相关操作的方法(可能多个view用到这些方法)。

    View:负责绘制、初始化UI;持有Presenter对象,view把与数据相关的业务逻辑都交给Presenter;持有没有数据的数据对象,数据需要presenter传递过来;一些点击后跳转一类的操作仍由其负责。

P:同时持有View和Model的引用;因为view需要把与数据相关的业务逻辑都交给Presenter,需要调用presenter,所以view是传参(即构造方法的形参传过来的);model没有办法主动从Presenter那拿回数据继续处理,也就是model没办法调用Presenter,所以model是实参。Presenter通知Model处理好数据并返回,调用了model的方法;Presenter拿到数据交给view展示,调用了view的方法(即view interface的方法);Presenter把数据交给model继续或者再次处理,调用了model的方法;上述三件事先后顺序根据具体情况决定,比如先获取数据调用model,再展示在UI上调用view,最后再存储数据调用model。

个人观点:MVP是View需要数据进行展示等相关操作(接口中的方法),于是便通知了presenter让其准备好数据;presenter本身并不持有数据,于是便让model获取数据并传给他,拿到数据后presenter自己并没有使用数据(不是全局变量);他把数据直接给了view让其去使用(是全局变量),同时把数据给了model让其继续处理;当view需要同样数据时可以自身获取,当view需要经过另外一种处理方式后的数据时便再次通知presenter。

 

MVP有很多优点,易于维护、易于测试、松耦合、复用性高、健壮稳定、易于拓展等。但是,由于Presenter经常性地需要执行一些耗时操作(等待Model执行完耗时操作),而Presenter持有了activity的强引用,如果在耗时操作结束前activity就被销毁了,就会导致Presenter一直持有activity对象,使得activity对象无法被回收,此时就发生了内存泄漏。

我们可以通过弱引用和activity、fragment的生命周期来解决这个问题。首先建立一个Presenter抽象,我们命名为BasePresenter,他是一个泛型类,泛型类型为view角色要实现的接口类型。具体代码如下:

 

public abstract class BasePresenter<V> {
    /**@Field: (View接口类型的弱引用) */
    protected Reference<V> mViewRef;

    /**
     * 建立关联
     * @param view
     */
    public void attachView(V view){
        mViewRef=new WeakReference<V>(view);
    }

    /**
     * 解除关联
     */
    public void detachView(){
        if (mViewRef!=null){
            mViewRef.clear();
            mViewRef=null;
        }
    }

    /**
     * 判断是否与View建立了关联
     * @return
     */
    public boolean isViewAttached(){
        return mViewRef!=null&&mViewRef.get()!=null;
    }

    /**
     * 获取View
     * @return
     */
    protected V getView(){
        return mViewRef.get();
    }
}

 

view类型通过BasePresenter的泛型类型传递进去,Presenter对这个view持有弱引用。通常情况下这个view类型应该是实现了某个特定接口的activity或者fragment等类型。

创建一个BaseActivity基类,通过这个基类的生命周期函数来控制它与Presenter的关系,相关代码如下:

 

public abstract class BaseActivity<V,P extends BasePresenter<V>> extends Activity{
    /**@Field: (与Presenter建立关系) */
    protected P mPresenter;

    /**
     * 创建Presenter
     * @return
     */
    protected abstract P createPresenter();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mPresenter=createPresenter();
        mPresenter.attachView((V)this);
    }

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


同理,BaseFragment相关代码如下:

 

 

public abstract class BaseFragment<V,P extends BasePresenter<V>> extends Fragment {
    /**@Field: (与Presenter建立关系) */
    protected P mPresenter;

    /**
     * 创建Presenter
     * @return
     */
    protected abstract P createPresenter();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mPresenter=createPresenter();
        mPresenter.attachView((V)this);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mPresenter.detachView();
    }
}

 

 

 

 

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值