31.Android MVP模式

31.Android MVP模式


Android MVP介绍

先说说MVC吧,MVC(Model-View-Controller)是Java中一种非常常用的开发模式。但是在Android中,View的话可以很容易想到Activity和Fragment,但是Controller的话,我们怎么想都还是Activity,因为无论是Activity还是Fragment跳转的话,都要执行startActivity所以无论怎么想,Controller都是由Activity在兼职。

Activity身兼View和Controller的职位,导致代码过度耦合,上千行也是常有的。

MVP(Model-View-Presenter)MVP的主要思想:

Activity或Fragment的UI逻辑对象抽象成View Interface,业务逻辑抽象成Presenter Interface,M不变。

Activity上只做简单回调接口的数据渲染,组件的简单操作。剩下的耗时工作(网络请求)都交给Presenter去执行。Presenter是Model和View的桥梁,Presenter处理网络请求后拿到的数据实例化Model,然后再将Model通过View Interface回调给View。

MVC 和 MVP 的区别: MVP中的View不能对Model直接操作。


Android MVP UML图

mvp_uml


Android MVP实现

实体类 - Topic

public class Topic {
    /**
     * 用户Id
     */
    public Long userId;
    /**
     * 主题Id
     */
    public Long topicId;
    /**
     * 主题内容
     */
    public String content;
}

Presenter层回调View层接口 - IMvpView

public interface IMvpView {
    /**
     * 添加成功
     * @param topic
     */
    void addSuccess(Topic topic);

    /**
     * 删除成功
     * @param topic
     */
    void delSuccess(Topic topic);

    /**
     * 修改成功
     * @param newTopic
     */
    void modSuccess(Topic newTopic);

    /**
     * 查询成功
     * @return
     */
    void querySuccess(List<Topic> topics);

    /**
     * 发生错误
     */
    void error();
}

Model层 接口 - ITopicModel

public interface ITopicModel {
    /**
     * 添加Topic
     *
     * @param topic
     */
    void add(Topic topic);

    /**
     * 删除主题
     *
     * @param topic
     */
    void del(Topic topic);

    /**
     * 修改主题
     *
     * @param topicId
     * @param topic
     */
    void mod(Long topicId, Topic topic);

    /**
     * 查询主题
     *
     * @return
     */
    void query();
}

Model层回调Presenter层抽象类 - TopicModelCallBack

public abstract class TopicModelCallBack {
    /**
     * 添加成功
     *
     * @param topic
     */
    public void addSuccess(Topic topic) {
    }

    /**
     * 删除成功
     *
     * @param topic
     */
    public void delSuccess(Topic topic) {
    }

    /**
     * 修改成功
     *
     * @param newTopic
     */
    public void modSuccess(Topic newTopic) {
    }

    /**
     * 查询成功
     *
     * @return
     */
    public void querySuccess(List<Topic> topics) {
    }

    /**
     * 发生错误
     */
    public abstract void error();
}

Model 实现类 - TopicModel

public class TopicModel implements ITopicModel {

    private TopicModelCallBack callBack;

    public TopicModel(TopicModelCallBack callBack) {
        this.callBack = callBack;
    }

    /**
     * 添加Topic
     *
     * @param topic
     */
    @Override
    public void add(Topic topic) {
        // TODO ...网络请求后...

        // TODO 返回数据 这里默认为返回原数据
        this.callBack.addSuccess(topic);
    }

    /**
     * 删除主题
     *
     * @param topic
     */
    @Override
    public void del(Topic topic) {
        // TODO ...网络请求后...

        // TODO 返回数据 这里默认为返回原数据
        this.callBack.delSuccess(topic);
    }

    /**
     * 修改主题
     *
     * @param topicId
     * @param topic
     */
    @Override
    public void mod(Long topicId, Topic topic) {
        // TODO ...网络请求后...

        // TODO 返回数据 这里默认为返回原数据
        this.callBack.modSuccess(topic);
    }

    /**
     * 查询主题
     *
     * @return
     */
    @Override
    public void query() {
        // TODO ...网络请求后...

        // TODO 返回数据
        Topic topic = new Topic();
        topic.userId = 267L;
        topic.topicId = 1267L;
        topic.content = "Save you from anything";
        List<Topic> list = new LinkedList<Topic>();
        list.add(topic);
        this.callBack.querySuccess(list);
    }
}

Presenter层 - MvpPresenter

public class MvpPresenter {
    private IMvpView iView;
    private ITopicModel model;

    public MvpPresenter(IMvpView iView) {
        this.iView = iView;
        this.model = new TopicModel(new TopicModelCallBack() {
            /**
             * 添加成功
             *
             * @param topic
             */
            @Override
            public void addSuccess(Topic topic) {
                MvpPresenter.this.iView.addSuccess(topic);
            }

            /**
             * 删除成功
             *
             * @param topic
             */
            @Override
            public void delSuccess(Topic topic) {
                MvpPresenter.this.iView.delSuccess(topic);
            }

            /**
             * 修改成功
             *
             * @param newTopic
             */
            @Override
            public void modSuccess(Topic newTopic) {
                MvpPresenter.this.iView.modSuccess(newTopic);
            }

            /**
             * 查询成功
             *
             * @param topics
             * @return
             */
            @Override
            public void querySuccess(List<Topic> topics) {
                MvpPresenter.this.iView.querySuccess(topics);
            }

            /**
             * 发生错误
             */
            @Override
            public void error() {
                MvpPresenter.this.iView.error();
            }
        });
    }

    /**
     * 添加主题
     *
     * @param topic
     */
    public void addTopic(Topic topic) {
        this.model.add(topic);
    }

    /**
     * 删除主题
     *
     * @param topic
     */
    public void delTopic(Topic topic) {
        this.model.del(topic);
    }

    /**
     * 修改主题
     *
     * @param topic
     */
    public void modTopic(Topic topic) {
        this.model.mod(topic.topicId, topic);
    }

    /**
     * 查询主题
     */
    public void queryTopic() {
        this.model.query();
    }


}

Activity

public class MvpActivity extends AppCompatActivity implements IMvpView {

    private TextView addTV;
    private TextView delTV;
    private TextView modTV;
    private TextView queryTV;

    private MvpPresenter presenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_mvp);

        this.addTV = (TextView) this.findViewById(R.id.add_tv);
        this.delTV = (TextView) this.findViewById(R.id.del_tv);
        this.modTV = (TextView) this.findViewById(R.id.mod_tv);
        this.queryTV = (TextView) this.findViewById(R.id.query_tv);

        this.presenter = new MvpPresenter(this);

        Topic topic = new Topic();
        topic.userId = 267L;
        topic.topicId = 1267L;
        topic.content = "Save you from anything";

        this.presenter.addTopic(topic);
        this.presenter.delTopic(topic);
        this.presenter.modTopic(topic);
        this.presenter.queryTopic();

    }

    /**
     * 添加成功
     *
     * @param topic
     */
    @Override
    public void addSuccess(Topic topic) {
        Log.i("MvpActivity", topic.content);
        this.addTV.setText("Add:"+topic.content);
    }

    /**
     * 删除成功
     *
     * @param topic
     */
    @Override
    public void delSuccess(Topic topic) {
        Log.i("MvpActivity",topic.content);
        this.delTV.setText("Del:"+topic.content);
    }

    /**
     * 修改成功
     *
     * @param newTopic
     */
    @Override
    public void modSuccess(Topic newTopic) {
        Log.i("MvpActivity", newTopic.content);
        this.modTV.setText("Mod:" + newTopic.content);
    }

    /**
     * 发生错误
     */
    @Override
    public void error() {

    }

    /**
     * 查询成功
     *
     * @param list
     * @return
     */
    @Override
    public void querySuccess(List<Topic> list) {
        Topic topic = list.get(0);
        Log.i("MvpActivity",topic.content);
        this.queryTV.setText("Query:"+topic.content);
    }
}

Android MVP项目结构

mvp_project


Android MVP作用

  • 在Android上,分离了View和Controller,大大降低了耦合度。

  • Activity只处理简单的事情,代码干净。

  • Presenter被抽象出来可以有多种具体的实现,方便进行单元测试。

  • Presenter和View都独立出来了,不互相耦合,提升了各自功能的特点和可读性(比如Presenter就是干这个的,View是干这个的,很容易看出来)。

  • 网络的耗时任务内,可能Activity的引用还被耗时任务引用着,这样会造成内存泄露,如果业务逻辑交给Presenter,可以在onDestory的时候让Presenter分离耗时任务和Activity的引用。


代码下载

Mvp4Android Demo

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值