MVP即Model-View-Presenter,是从经典的MVC演变而来的,它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理、Model提供数据、View负责显示。
一,结构
在MVP中,View并不直接与Model通信,而是通过Presenter间接进行的,即所有的交互都发生在Presenter内部,以改进:
1 2 3 4 5 6
| void View::onKeyDown() override { std::cout << "View: mpModel->getData() < 100 ?" << std::endl; if (mpModel->getData() < 100) mpController->increaseData(); }
|
区别在于,MVC是系统级的架构,而MVP是用在某个特定页面上的,也就是说MVP的灵活性要远远大于MVC(因为所有业务代码均放置在Presenter中),实现起来也极为简单。
二,优缺点
优点
- 模型与视图完全分离,使得修改视图不影响模型
- 能更高效地使用模型,因为所有的交互都发生在Presenter内部
- 一个Presenter可用于多个视图,而不需要改变Presenter的逻辑(视图的变化总是比模型的变化频繁)
- 可脱离用户接口(View)进行单元测试(Presenter中的业务逻辑)
缺点
由于对视图的渲染放在了Presenter中,所以视图和Presenter的交互会过于频繁。还有一点需要明白,如果Presenter过多地渲染了视图,往往会使得它与特定的视图的联系过于紧密。一旦视图需要变更,那么Presenter也需要变更了。比如说,原本用来呈现Html的Presenter现在也需要用于呈现Pdf了,那么视图很有可能也需要变更。
详情请参考百度百科——MVP。
三,代码示例
模型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class : public AbstractModel { public: Model() { mData = 98; }
int getData() override { return mData; } void setData(int data) override { mData = data; std::cout << "Model: data is updated" << std::endl; }
private: int mData; };
|
视图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class View : public AbstractView { public: View(AbstractPresenter* pPresenter) { mpPresenter = pPresenter; } void display(int data) override { std::cout << "View: Display " << data << std::endl; }
void onKeyDown() override { std::cout << "View: call mpPresenter to handle it" << std::endl; mpPresenter->increaseData(); }
private: AbstractPresenter* mpPresenter; };
|
主持者
1 2 3 4 5 < 大专栏 MVP简要示例span class="line">6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| class Presenter : public AbstractPresenter { public: Presenter(AbstractModel* pModel) { mpModel = pModel; mpView = new View(this); mpView->display(pModel->getData());
std::cout << "User: onKeyDown" << std::endl; mpView->onKeyDown(); std::cout << "User: onKeyDown" << std::endl; mpView->onKeyDown(); std::cout << "User: onKeyDown" << std::endl; mpView->onKeyDown(); std::cout << "User: onKeyDown" << std::endl; mpView->onKeyDown(); std::cout << "User: onKeyDown" << std::endl; mpView->onKeyDown(); } ~Presenter() { delete mpView; }
void increaseData() override { std::cout << "Presenter: mpModel->getData() < 100 ?" << std::endl; if (mpModel->getData() < 100) { std::cout << "Presenter: increaseData" << std::endl; mpModel->setData(mpModel->getData() + 1); std::cout << "Presenter: send the data which needs displaying" << std::endl; mpView->display(mpModel->getData()); } }
private: AbstractModel* mpModel; AbstractView* mpView; };
|
主程序及运行结果
1 2 3 4 5 6 7 8 9 10 11 12
| int main() { AbstractModel* pModel = new Model; AbstractPresenter* pPresenter = new Presenter(pModel); delete pPresenter; delete pModel;
system("pause"); return 0; }
|
附:完整源码包
四,推荐学习
项目介绍
待办事项软件(Android、MVP),它是谷歌提供用于学习的其中一个项目样例。README.md文件已对其作出相应的说明,此处不再赘述。另外,可查看其它分支学习如何使用其它的框架实现该应用软件。
给完全小白的一些建议
- Clone该项目或下载其Zip后解压后,使用Android Studio打开该项目
- 点击菜单栏Build下的”Make Project”,若失败根据提示进行操作即可,直至成功
- 点击菜单栏Run下的”Run ‘app’”
- 在真实安卓机或虚拟安卓机下了解该软件的实际运行情况
- MVP框架相关的代码分析
- 体会、总结其组织、规范相关接口代码的方式