博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一个简单的MVP模式案例
阅读量:6985 次
发布时间:2019-06-27

本文共 4085 字,大约阅读时间需要 13 分钟。

1. 问题背景

首先需要清楚的一点是MVP模式的设计初衷是:为了解决在MVC模式中,过于复杂的逻辑和界面之间的交互中Activity的职责不单一的问题,Activity既充当了View层,又充当了Controller层的角色。刨除问题的复杂度,直接谈MVP模式的优越性,都是耍流氓。

这也就是为什么我们很多人,为什么不愿意学习MVP的原因。但是如果遇到了一个比较复杂的问题,MVP的解耦能够让你更加轻松地应对需求的迭代。

本文将一个案例来解释MVP模式的设计方法,但是这里有一个矛盾点:MVP模式本身应该作用于较复杂问题的,但是本文作为入门文章又必须使用一个较简单的场景去设计,这样才能容易看出MVP的结构。

场景描述如下:

APP中有一本书(Model),书本的价格会显示在Activity(View)中,Activity中有两个按钮,可以对书本的价格进行控制(Presenter)。

2. MVP模式的实现

基于上面提出的场景,我们先简单的设计界面:

复制代码

我们设计书本的数据模型BookVo

public class BookVo {    private String name;    private int price;    private String author;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getPrice() {        return price;    }    public void setPrice(int price) {        this.price = price;    }    public String getAuthor() {        return author;    }    public void setAuthor(String author) {        this.author = author;    }    @Override    public String toString() {        final StringBuffer sb = new StringBuffer("BookVo{");        sb.append("name='").append(name).append('\'');        sb.append(", price=").append(price);        sb.append(", author='").append(author).append('\'');        sb.append('}');        return sb.toString();    }}复制代码

Activity只负责显示书本的信息,不参与涨价/降价的逻辑处理,所以我们需要创建一个Presenter类,把价格逻辑交给他处理,处理完之后再在Activity中显示。

Presenter类应该具有涨价/降价的能力,因此我们把Presenter设计成接口更加合理。IPresenter.java的内容如下:

public interface IPresenter {    void increasePrice();    void decreasePrice();}复制代码

再设计一个PresenterImpl类继承IPresenter接口,并实现涨价和降价的两个方法。因为需要在Presenter中操作Model,并在View中显示,所以Presenter需要持有Model和View的对象。Model对象很简单,直接将BookVo传给Presenter即可,但是View对象如何处理呢?

我们制定一个IView接口,向Presenter暴露我们能够提供的能力,比如这个场景里的显示书籍信息,于是IView接口内容如下:

public interface IView {    void showBookInfo(BookVo vo);}复制代码

我们让MainActivity实现IView接口,

@Overridepublic void showBookInfo(BookVo vo) {    this.mDescTv.setText(vo.toString());}复制代码

现在我们只需要给Presenter添加一个构造方法就行,构造方法中添加两个参数:BookVo和IView对象。PresenterImpl.java代码如下:

public class PresenterImpl implements IPresenter {    private IView mIView;    private BookVo mBookVo;    public PresenterImpl(IView iView, BookVo vo) {        this.mIView = iView;        this.mBookVo = vo;    }    @Override    public void increasePrice() {        Log.i("lxc", " ---> 涨价了一元");        mBookVo.setPrice(mBookVo.getPrice() + 1);        this.mIView.showBookInfo(mBookVo);    }    @Override    public void decreasePrice() {        Log.i("lxc", " ---> 降价了一元");        mBookVo.setPrice(mBookVo.getPrice() - 1);        this.mIView.showBookInfo(mBookVo);    }}复制代码

MainActivity代码如下:

public class MainActivity extends AppCompatActivity implements IView{    private TextView mDescTv;    private Button mIncreaseBtn, mDecreaseBtn;    private IPresenter mPresenter;    private BookVo vo;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initData();        initPresenter();        mDescTv = findViewById(R.id.desc);        mIncreaseBtn = findViewById(R.id.increase);        mDecreaseBtn = findViewById(R.id.decrease);        mIncreaseBtn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                mPresenter.increasePrice();            }        });        mDecreaseBtn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                mPresenter.decreasePrice();            }        });        mDescTv.setText(vo.toString());    }    private void initData() {        vo = new BookVo();        vo.setName("《百年孤独》");        vo.setAuthor("泰戈尔");        vo.setPrice(100);    }    private void initPresenter() {        mPresenter = new PresenterImpl(this, vo);    }        @Override    public void showBookInfo(BookVo vo) {        this.mDescTv.setText(vo.toString());    }}复制代码

现在就可以看到效果了。

3.若干思考

  1. MVP与MVC有什么区别?有本质区别么?
  2. 案例中P层和M层为什么要设计成接口?

4. 后续

本文中的Demo源码和思考答案将存在于我的微信公众号中,获取源码(Source)请回复"S2",获取答案(Answer)请回复"A2"。另外欢迎大家关注我的微信公众号~么么么

转载地址:http://wsqpl.baihongyu.com/

你可能感兴趣的文章
浙大pat甲级题目---1021. Deepest Root (25)
查看>>
CCRD_TOC_2008年第2期
查看>>
脊柱关节病外周关节滑膜高表达的RANK/RANKL/OPG系统与炎症呈部分分离
查看>>
vue Cli 脚手架的搭建
查看>>
springboot配置Filter的两种方法
查看>>
substringToIndex substringFromIndex
查看>>
开源方案搭建可离线的精美矢量切片地图服务-1.开篇(附成果演示地址)
查看>>
UVA 1613 K-Graph Oddity K度图着色 (构造)
查看>>
Docker版本(三)
查看>>
汇编小知识
查看>>
eclipse使用git提交本地项目,提交至远程github上
查看>>
out对象的使用
查看>>
python3随记——字符编码
查看>>
第八章教材内容总结:异常控制流
查看>>
静态化
查看>>
我对CopyOnWrite的思考
查看>>
架构师修练 I - 超级代码控
查看>>
eclipse总是自动跳到ThreadPoolExecutor解决办法
查看>>
zabbix3.0.4添加对指定进程的监控
查看>>
dojo/domReady! 中感叹号的作用
查看>>