浅析MVP设计模式

一、何为MVP

说起MVP模式,必须先从MVC这种传统的设计模式说起,一般传统的app页面布局的设置逻辑和业务处理了逻辑都写在activity层中,这样随着项目的迭代,老的代码将也来越乱,每次需求更改,业务数据层的逻辑更改和界面层的逻辑更改都将在activity中修改,如果是自己写的还好,若是上个哥们的项目,而且还写的很乱的,那么你懂得。
先盗一张图,因为我们要用这张图来解释。

MVC模式中View层和Model层都跟controller层关联,每次业务逻辑的更改都基本要在同一个类中修改,众所周知,写代码不难,改代码那是灾难啊,特别还不是自己的写的代码,这个时候那种感觉你懂得。如果采用MVP的话,将业务逻辑Model层和视图层分开,那么该需求的时候我们操作就好做点。比如改页面的页面变化修改view层代码,model层变化在model层改,这样更清晰。理论离不开实战,接下来用代码层讲解吧。

二、工程

工程结构如下:


adapter不解释了,bean这个也不解释了,model为数据处理类,view为视图逻辑层,presenter为中间层负责链接俩层。
1、model层处理:
定义一个接口规范:IGirlModel
public interface IGirlModel {

    void loadGirl(GrilOnLoadListener listener);

    interface GrilOnLoadListener{

        void onComplete(List<Girl> girls);

    }
}
接着是其实现类,负责填充数据:
public class GirlModelImpl implements IGirlModel{

    @Override
    public void loadGirl(GrilOnLoadListener listener) {
        //加载数据
        List<Girl> data = new ArrayList<>();
        data.add(new Girl("刘亦菲","https://gss0.bdstatic.com/94o3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike116%2C5%2C5%2C116%2C38/sign=a38cb7e5af1ea8d39e2f7c56f6635b2b/c2fdfc039245d6884449b2faadc27d1ed21b2420.jpg"));
        data.add(new Girl("杨幂","https://gss1.bdstatic.com/9vo3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike116%2C5%2C5%2C116%2C38/sign=4cd858ed9f0a304e462fa8a8b0a1cce3/d53f8794a4c27d1e63dc172d13d5ad6edcc43864.jpg"));
        data.add(new Girl("唐嫣","https://gss2.bdstatic.com/9fo3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike180%2C5%2C5%2C180%2C60/sign=ac5b0fe02d381f308a1485fbc868276d/08f790529822720e3e87df227ecb0a46f31fab98.jpg"));
        data.add(new Girl("景甜","https://gss0.bdstatic.com/94o3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike180%2C5%2C5%2C180%2C60/sign=c9b60227d52a6059461de948495d5ffe/30adcbef76094b363416f503a1cc7cd98c109d5c.jpg"));
        data.add(new Girl("赵丽颖","https://gss3.bdstatic.com/7Po3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike150%2C5%2C5%2C150%2C50/sign=826890e23a01213fdb3e468e358e5db4/48540923dd54564e9d204002b0de9c82d1584f47.jpg"));
        data.add(new Girl("Angelababy","https://gss1.bdstatic.com/-vo3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike116%2C5%2C5%2C116%2C38/sign=005e5fcd9aef76c6c4dff379fc7f969f/9358d109b3de9c8234db74636681800a18d843a4.jpg"));
        data.add(new Girl("孙俪","https://gss3.bdstatic.com/-Po3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike80%2C5%2C5%2C80%2C26/sign=e82ca234a18b87d6444fa34d6661435d/203fb80e7bec54e76de10a1bb9389b504fc26aa1.jpg"));

        //返回数据
        listener.onComplete(data);
    }
}
2、View层处理
该类主要定义一些页面操作,由activity去实现完成
/**
 * 视图层接口
 */
public interface IGrilView {

    /**
     * 加载提示
     */
    void showLoading();

    /**
     * 显示数据
     * @param data
     */
    void showGirls(List<Girl> girls);

}
3、presenter层
主要负责链接俩层将逻辑串起来
public class GirlPresenter {

    //View引用
    IGrilView mGirlView;
    //Model引用
    IGirlModel girlModel =  new GirlModelImpl();

    public GirlPresenter(IGrilView mGirlView) {
        this.mGirlView = mGirlView;
    }

    //
    public void fetch(){
        //显示进度条
        if (girlModel != null) {
            //显示进度条
            if (mGirlView != null) {
                mGirlView.showLoading();
            }

            girlModel.loadGirl(new IGirlModel.GrilOnLoadListener() {
                @Override
                public void onComplete(List<Girl> girls) {
                    //返回数据

                    //显示到view层
                    mGirlView.showGirls(girls);
                }
            });
        }

        //加载数据

    }
}
4、activity中调用
public class MainActivity extends AppCompatActivity implements IGrilView {

    private ListView listView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listView = (ListView) findViewById(R.id.lv);


        new GirlPresenter(this).fetch();
    }

    @Override
    public void showLoading() {
        Toast.makeText(this, "正在加载中...", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void showGirls(List<Girl> girls) {
        listView.setAdapter(new GirlAdapter(this,girls));
    }


}

5、优化

此时项目效果已将出来了,但是这种情况是存在问题的,问题就出在presenter层,该层持有view层的引用,而view层接口的实现都是activity,那么这时候就有内存泄漏了。怎么解决呢,其实简单的解决就是让view层的引用是弱引用,这样gc会在内存不足的时候将这个对象回收掉,这样就避免了内存泄漏,代码如下:
public class GirlPresenter {
    //View引用
//    IGrilView mGirlView;
    WeakReference<IGrilView> mGirlView;
    //Model引用
    IGirlModel girlModel = new GirlModelImpl();

    public GirlPresenter(IGrilView mGirlView) {
        this.mGirlView = new WeakReference<IGrilView>(mGirlView);
    }

    //
    public void fetch(){
        //显示进度条
        if (girlModel != null) {
            //显示进度条
            if (mGirlView != null) {
                mGirlView.get().showLoading();
            }

            girlModel.loadGirl(new IGirlModel.GrilOnLoadListener() {
                @Override
                public void onComplete(List<Girl> girls) {
                    //返回数据

                    //显示到view层
                    mGirlView.get().showGirls(girls);
                }
            });
        }

        //加载数据

    }
}

6、源码




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值