android 的MVP模式的介绍

    当下开发中使用最多的最普遍的有三种模式就是MVC,MVP和MVVM。相信大家对这三个名词并不陌生,他们在我们的开发用应用的及其广泛,今天我就浅谈一下我了解的MVP设计模式。说MVP之前不得不谈谈MVC模式,MVP 是从经典的模式MVC演变而来,它们的基本思想有相通的地方我们充分的认识了MVC的不足,才能更好地使用MVP。希望大家看完都有所收获。

转载请标明出处:


本文来自【周焰权的博客】

首先给出MVC和MVP的结构图,现在具体说一下MVC的不足


 https://i-blog.csdnimg.cn/blog_migrate/7880dc0243dd9d9b2fdc511650418a33.png

 

(1)View层和Controller层任务分工不明

Controller负责逻辑的处理,Model提供数据,View负责显示。当我们在android开发中想要动态的添加一些视图控件的时候,你可能会在Activity的代码中添加。咋一看并没有什么错,合情合理。但你认为这样很好吗?

答案肯定是否定的,因为在这里Activity既当妈(View)又当了爹(Controller),是的layout.xml的控制力变弱,影响了各层的性能。这样也不利于团队的开发

(2)View层和Model的耦合度高

细心的同学估计已经看出MVC结构图,View层和Model是相互联系的,存在耦合关系初期的小项目和能接受,但严重影响之后程序的可扩展性,会让代码的可读性越来越差。如果你想更换项目中的部分代码,你会发现了太难了,这些零散的类散布的到处都是。不仅如此,因为有一些业务逻辑在View里实现了,导致要更改View也是比较困难的,至少那些业务逻辑是无法重用的。所以今天来谈谈MVP模式。

MVP模式结构

  • Model: 业务逻辑和实体模型
  • View:用户交互和视图显示,在android中对应activity
  • Presenter: 负责完成View于Model间的逻辑和交互
可以说MVP是MVC的升级 View和Model的分离,View只负责View有关的,如果你要操作View层发出事件给Presenter,让Presenter来操作Model,等Model操作完成后再操作View层,不用你再去考虑View和mOd el的耦合问题了,接下来看看具体的代码演示。

  首先你要有个请求数据的类

public interface GetData {
    //去请求数据
    @Headers({"Content-Type:application/json; charset=UTF-8"})//请求头
    @POST(value = "v1/tag/cartoon")//后半部分的请求地址
    Call<Cartoon> getListData(@Query("page_size ") String page_size,
                              @Query("page") String page);
}

 然后请求是否成功的回掉

public interface OnGetDataListenser {
    //请求成功这里的Cartoon是你的bean    void onSuccessGetDataListener(Cartoon cartoon);
    //失败
    void onFailGetDataListener(String erro);
}

在然后你要有个Model的管理接口,要知道MVP其实就是一种更纯粹的面向对象编程,它直接面向接口

public interface INetWorkModel {
    //请求数据
    void loadData(int page);
}

   然后用NetWorkModel去实现INetWorkModel这个接口,实现他的方法

  

public class NetWorkModel implements INetWorkModel {


    OnGetDataListenser onGetDataListenser;


    public NetWorkModel(OnGetDataListenser onGetDataListenser){
        this.onGetDataListenser = onGetDataListenser;
    }
    //加载数据
    @Override
    public void loadData(int page) {
        HttpUtils httpUtils = HttpUtils.getHttpUtils();
        //进行网络请求
        httpUtils.getListData("http://api.menghuoapp.com/",page+"");

        httpUtils.setOnGetDataListenser(onGetDataListenser);

    }
}

这里的数据请求,用个单例模式

public class HttpUtils {

    private OnGetDataListenser onGetDataListenser;

    public void setOnGetDataListenser(OnGetDataListenser onGetDataListenser){
        this.onGetDataListenser = onGetDataListenser;
    }

    //提供一个对象:使用单例模式
    private static HttpUtils httpUtils;
    public static HttpUtils getHttpUtils(){
        if(httpUtils==null){
            httpUtils = new HttpUtils();
        }
        return httpUtils;
    }

    //进行网络请求数据
    //baseUrl:请求接口的前半部分
    public void getListData(String baseUrl,String page){
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(baseUrl)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        GetData getData =  retrofit.create(GetData.class);

        Call<Cartoon> call =getData.getListData("5",page);
        call.enqueue(new Callback<Cartoon>() {
            @Override
            public void onResponse(Call<Cartoon> call, Response<Cartoon> response) {

              if(onGetDataListenser!=null){
                  onGetDataListenser.onSuccessGetDataListener(response.body());
              }
            }

            @Override
            public void onFailure(Call<Cartoon> call, Throwable t) {
                if(onGetDataListenser!=null){
                    onGetDataListenser.onFailGetDataListener(t.getMessage());
                }
            }
        });
    }

}
这是Model层的几个类,我们来写Persenter的类还记不记得之前的监听回调接口 ,让Persenter类去实现

public class NetWorkPresenter implements OnGetDataListenser{
    INetWorkView iNetWorkView;
    INetWorkModel iNetWorkModel;

    public NetWorkPresenter(INetWorkView iNetWorkView){
        this.iNetWorkView = iNetWorkView;
        iNetWorkModel = new NetWorkModel(this);
    }

    public void getListData(int page){
        iNetWorkModel.loadData(page);
    }

    @Override
    public void onSuccessGetDataListener(Cartoon cartoon) {
        iNetWorkView.setData(cartoon);
    }

    @Override
    public void onFailGetDataListener(String erro) {
        iNetWorkView.setFailMessage(erro);

    }
}

始终记住面向对象的思想,我们定义View的管理接口

public interface INetWorkView {

    //ListView的数据
    void setData(Cartoon cartoon);

    //请求失败的信息
    void setFailMessage(String erro);
}

同样让你要展示的View类来实现这个接口

public class NetWorkActivity extends AppCompatActivity implements INetWorkView{


    private ListView lv;
    private NetWorkPresenter netWorkPresenter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_net_work_activitye);

        lv = (ListView) findViewById(R.id.lv);

        //进行网络请求
     netWorkPresenter = new NetWorkPresenter(this);
        netWorkPresenter.getListData(1);
    }

    @Override
    public void setData(Cartoon cartoon) {
        //cartoon 是数据源
        //adapter
        //使用Adapter将数据展示到ListView
        lv.setAdapter(new MyAdapter(NetWorkActivity.this,cartoon.getData()));
        Log.e("AAA","请求成功"+cartoon.getMsg());
        Log.e("AAA","请求成功"+cartoon.getData().size());
    }

    @Override
    public void setFailMessage(String erro) {
        Log.e("AAA","请求失败"+erro);
    }
}

同样给出自定义的adapter的类和bean类

public class MyAdapter extends BaseAdapter {

    private Context context;
    private List<Cartoon.DataBean> list ;
    public MyAdapter(Context context, List<Cartoon.DataBean> list){
        this.context= context;
        this.list = list;
    }
    @Override
    public int getCount() {
        return list==null?0:list.size();
    }

    @Override
    public Object getItem(int position) {
        return list.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ImageView imageView = new ImageView(context);
        Picasso.with(context).load(list.get(position).getPic_url()).into(imageView);
        return imageView;
    }
}
public class Cartoon {

    private String msg;
    private int code;

    private List<DataBean> data;

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public List<DataBean> getData() {
        return data;
    }

    public void setData(List<DataBean> data) {
        this.data = data;
    }

    public static class DataBean {
        private String link;
        private String title;
        private String subtitle;
        private String pic_url;

        public String getLink() {
            return link;
        }

        public void setLink(String link) {
            this.link = link;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public String getSubtitle() {
            return subtitle;
        }

        public void setSubtitle(String subtitle) {
            this.subtitle = subtitle;
        }

        public String getPic_url() {
            return pic_url;
        }

        public void setPic_url(String pic_url) {
            this.pic_url = pic_url;
        }
    }
}

总结一下

      在处理复杂界面和逻辑时,我们可以对同一个activity将每一个业务都抽离成一 个Presenter,这样代码既清晰逻辑明确又方便我们扩展。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值