献给新手的MVP架构详解
目录
MVP
MVP架构总介绍
MVP各层详解
1. Model(模型)
2. View(视图)
3. Presenter(协调者)
4. 小结
MVP各层关系梳理
1. Model 与 Presenter 的关系
2. View 与 Presenter 的关系
3. Presenter 的核心协调作用
4. Model 与 View 的强制隔离
5. 一句话小结
MVP,MVC,MVVM三者做比
结语
MVP
MVP架构总介绍
经常网上冲浪的人:哎呀(¬‿¬)✧ ~,老爸得了M---V---P---......…… 啊呸!
MVP(是Model-View-Presenter这三者的首字母缩写)架构是一种软件设计模式,常用于开发用户界面。它的核心思想是将应用程序分为三个部分:Model(模型)、View(视图)和Presenter(协调者)。
想象一下,你正在经营一家小餐馆。为了更好地管理餐馆,你决定将工作分成三个部分:
- Model(模型):就像是你的厨房,负责准备食物(数据)。
- View(视图):就像是餐厅的前台,负责展示食物(数据)给顾客(用户)。
- Presenter(协调者):就像是店长,负责协调厨房和前台的工作,确保食物(数据)正确地展示给顾客(用户)。
可以说这是MVC框架设计的变形体,事实上这两种框架也存在很多的相同点。分层方式的核心特点由Controller变成了Presenter,当然,各层内部的定义以及相互之间的关系也做了很大改变,例如MVP框架中,就断绝了View与Model之间的直接交互,成功的减少了Activity中的臃肿代码,使得Activity能够保持整洁清晰。所以说与MVC的区别也就体现在这里。后续会详细介绍这样做的好处是能够让代码更清晰、更易于维护和测试。
我们先以一个常见的购物车例子来绘制一个直观的MVP架构下的数据流图,后续将详解这些关系,可以先在脑子里大致构建这么一个图可以方便后续理解:

MVP各层详解
1. Model(模型)
在 MVP 架构中,Model 层负责封装所有与数据和业务逻辑相关的操作,即“封装数据逻辑与业务规则的模块”。它通过服务类(如 CartService)向 Presenter(常说的P层) 提供清晰、可复用的接口,从而实现逻辑复用和关注点分离。
也可以换个角度来看,Model层就像是厨房,它的主要职责是处理数据。具体来说,Model层负责:
- 数据存储:比如从数据库中读取数据或写入数据。
- 业务逻辑:对数据进行处理,比如计算总价、验证数据等。
举个例子,如果你的餐馆需要一份菜单,Model层会负责从数据库中读取菜单数据,并进行必要的处理(比如分类、排序)。
2. View(视图)
在MVP架构中的View层(视图层)其实和MVC没有太大差别,同样是由xml文件以及Activity/Fragment完成。区别在于通常View需要实现一个逻辑接口,将View上的操作转交给Presenter进行实现,最后,Presenter 再调用View逻辑接口将结果返回给View元素。所以这就造成了MVP中的View层不再与Model层直接进行交互!!!
依旧也可以换个角度来看,View层就像是餐厅的前台,它的主要职责是展示数据和接收用户输入。具体来说,View层负责:
- 展示数据:将Model层提供的数据展示给用户。
- 接收输入:接收用户的操作(比如点击、输入),并将这些操作传递给Presenter层。
继续用餐馆的例子,View层就像是菜单板和点餐系统,它展示菜单给顾客,并接收顾客的点餐操作。
3. Presenter(协调者)
在MVP架构中的Presenter层,从他的英文单词来看有“主持人”的意思,我觉得这非常贴切,他就是作为一个主持人或者说中间人的身份,主持着Model与View之间的交互,在MVC中Activity内关于Model及View之间的交互都可以移入Presenter中,由Presenter完成这两层之间的交互。依旧强调这就使得了View与Model之间没有耦合,也将业务逻辑从View角色上抽离出来。
由于这一层是MVP中的真正“MVP”。所以我们再来以购物车的例子总的来看P层的职责与说明。
| 职责 | 说明 |
|---|---|
| 1. 接收 View 的用户操作 | 如点击“加入购物车”、输入搜索关键词等 |
| 2. 调用 Model 层获取/处理数据 | 可能调用多个 Model 或 Service |
| 3. 处理业务逻辑(部分) | 比如格式校验、状态判断、组合多个 Model 的结果 |
| 4. 决定如何更新 View | 不是简单“传递”,而是主动通知 View 做什么(如显示加载、成功、错误) |
| 5. 解耦 View 与 Model | View 完全不知道 Model 的存在,反之亦然 |
所以说没有 Presenter,MVP 就退化成“View 直接调 Model”——那就不是 MVP 了,而是混乱的紧耦合代码。
运用python代码写个demo例子也可以直观的看出:
# View(只负责展示和收集用户输入)
class ProductView:
def show_loading(self): ...
def show_success(self, msg): ...
def show_error(self, err): ...
# Presenter(核心协调者)
class ProductPresenter:
def __init__(self, view, cart_service, user_service):
self.view = view
self.cart_service = cart_service
self.user_service = user_service
def on_add_to_cart_clicked(self, product_id, quantity):
# 1️⃣ 先让 View 显示加载
self.view.show_loading()
try:
# 2️⃣ 检查用户是否登录(调用另一个 Model)
if not self.user_service.is_logged_in():
self.view.show_error("请先登录")
return
# 3️⃣ 调用 CartService(Model 层)
result = self.cart_service.add_to_cart(product_id, quantity)
# 4️⃣ 根据结果决定下一步(业务逻辑!)
if result["success"]:
self.view.show_success("已加入购物车!")
# 甚至可以触发其他操作:如更新购物车图标数量
self.update_cart_badge()
else:
self.view.show_error("库存不足")
except Exception as e:
self.view.show_error(str(e))
def update_cart_badge(self):
count = self.cart_service.get_item_count()
self.view.update_cart_icon(count) # ← 主动通知 View 更新某部分
说了这么多,也别忘了老传统,我们依然可以换个简单的角度来看,Presenter层就像是店长,它的主要职责是协调厨房(Model层)和餐厅前台(View层)的工作。具体来说,Presenter层负责:
- 处理业务逻辑:根据用户的操作,决定需要从Model层获取哪些数据,或者需要对Model层进行哪些操作。
- 更新View:根据Model层返回的数据,更新View层的展示内容。
依旧情景想象,在餐馆的例子中,Presenter层就像是店长,它根据顾客的点餐操作,告诉厨房(Model层)需要准备哪些菜品,然后根据厨房返回的菜品,更新前台的展示内容(View层)。
4. 小结
说了这么多相信你已有了对MVP架构以及该架构中的每一层都有了一个较为清晰的认识了。如果我们拉通一遍来看,我认为MVP架构可以比作一场优雅有序的“舞台剧”
| 角色 | 对应组件 | 职责 |
|---|---|---|
| 演员(只负责表演) | View | 显示界面、接收点击,但不思考“接下来该演什么” |
| 剧本与道具(故事世界规则) | Model | 定义商品、订单、用户等实体及其行为规则 |
| 导演(调度一切) | Presenter(核心!) | 决定:演员何时上场、用哪个道具、剧情如何推进、观众看到什么 |
在这里面的👑 导演(Presenter)才是让整部戏连贯、合理、可控的关键。
如果这是你第一次接触MVP架构时,遇到了在写代码时突然逻辑卡壳的情况的话,老夫(嘿嘿,不是)再教你一个焚决:
View 只会说:“用户点了我!”
Presenter 回答:“好,我来处理,你准备显示加载、成功或错误。”
Model 默默干活:“数据已处理,结果给你。”
MVP各层关系梳理
要介绍MVP各层的关系梳理,我们先从一张图来总观这三层之间的关系:

这张架构图就非常清晰的揭示了MVP的灵魂所在:Presenter是唯一枢纽,View与Model永不相见。
所有用户操作(点击/输入)从View出发 → 交由Presenter决策 → 驱动Model处理数据;
所有数据结果经Presenter“翻译加工” → 精准指挥View更新界面。
Model专注“做什么”(数据逻辑),View专注“怎么显”(界面渲染),Presenter专注“怎么办”(流程调度)——三者通过接口契约紧密协作,又因职责隔离而各自轻盈。
1. Model 与 Presenter 的关系
在 MVP 架构中,Model 层与 Presenter 层构成单向依赖关系:Presenter 主动调用 Model 提供的数据服务接口(购物车例子如 CartService.add_to_cart()),而 Model 仅专注于数据获取、持久化及核心业务规则的实现(如库存校验、价格计算),完全不感知 View 层的存在。这种设计确保了 Model 的高内聚与可复用性。例如同一份购物车逻辑可被商品详情页、列表页等多个 Presenter 安全调用,同时为单元测试提供清晰边界(可轻松 Mock Model 行为)。
也可以换个角度来看:
依旧Model 就像餐馆的后厨,Presenter 是店长。
顾客点“宫保鸡丁”(用户操作),店长(Presenter)立刻对后厨(Model)喊:“三号桌加一份宫保鸡丁,微辣!”
后厨专注炒菜(处理数据),完成后把菜递给店长:“搞定!”。
后厨从不问“这菜给谁吃”“摆盘要多好看”,店长也不插手“该放几勺糖”——各守本分,高效协作。
✅ 小彩蛋:可以想象如果后厨今天换大厨(就是重构 Model),只要出菜标准不变,店长和顾客完全无感!
2. View 与 Presenter 的关系
View 层与 Presenter 层通过接口紧密协作:View 仅负责渲染界面与捕获用户事件(如按钮点击),并将事件“上报”给 Presenter;Presenter 则根据业务逻辑,主动调用 View 暴露的更新方法(如 showLoading()、showSuccess())驱动界面状态变化。View 层被设计为“哑组件”(Dumb Component),不含任何业务判断逻辑,极大降低了 UI 与逻辑的耦合度,使界面替换(如 Web 改 App)或自动化测试变得轻而易举。
也可以换个角度来看:
View 就像前台服务员,Presenter 仍是店长。
服务员(View)只做三件事:
① 微笑递菜单(展示界面)
② 听清顾客说“加米饭”(捕获点击)
③ 立刻跑去找店长汇报(触发 Presenter 事件)
店长(Presenter)判断:“米饭有库存,让后厨加一份”,再对服务员说:“去端碗米饭,顺便说‘米饭免费哦’”。
服务员绝不自作主张:“这桌像土豪,多送俩菜?”——所有决策权归店长!
✅ 小彩蛋:今天服务员请假(就是换 UI 框架),新来的只要听懂店长指令,服务流程照常运转!
3. Presenter 的核心协调作用
Presenter 是 MVP 架构的“神经中枢”与“决策引擎”。它接收 View 的原始事件,协调调用多个 Model 服务(如同时调用用户服务校验登录态、调用购物车服务提交订单),处理 UI 相关的流程逻辑(如“加购成功后弹窗+更新购物车图标+埋点上报”),并精准驱动 View 的状态流转(加载中→成功→恢复常态)。Presenter 的存在,使复杂交互流程变得清晰可控,同时将业务规则与界面细节彻底分离。
依旧可以换个角度来看:
Presenter 就是全能店长,全场灵魂人物!
顾客说“打包带走”(用户操作):
→ 店长先问后厨:“打包盒够吗?”(调用 Model)
→ 发现库存不足,立刻对服务员说:“跟顾客说送环保袋,再递张优惠券”(更新 View)
→ 同时记小本本:“今天打包需求多,明天多备盒子”(触发埋点)
店长不炒菜、不端盘,却让整个餐馆运转如钟表!
✅ 小彩蛋:店长手机存着《服务 SOP 手册》(就是Presenter 逻辑),新店长上岗三天就能无缝接管!
4. Model 与 View 的强制隔离
在严格 MVP 实现中,Model 与 View 之间零直接交互:View 无法访问 Model 数据,Model 变化也不会自动触发 View 更新。所有数据流必须经由 Presenter 中转。这种“物理隔离”杜绝了“在界面代码里写数据库查询”的混乱,使代码边界清晰、职责分明,极大提升可维护性与团队协作效率(前端专注 View,后端专注 Model)。
依旧可以换个角度来看:
后厨(Model)和前台(View)之间隔着一堵实心墙!
顾客好奇探头问后厨:“辣椒放了吗?”——服务员立刻拦住:“先生请坐,我帮您问店长!”
后厨炒完菜也不会喊“菜好啦!”,而是放在传菜口,等店长(Presenter)取走。
这堵墙看似麻烦,实则保护:
🔥 后厨专注火候,不受顾客干扰
🎨 前台专注服务,不被油烟熏到
🛡️ 食品安全(代码安全)有保障!
5. 一句话小结
View 只管“说”和“看”,Model 只管“做”和“存”,Presenter 全程“想”和“派”——各司其职,默契如交响乐团!
所以说当我们下次写代码时,可以不妨自问:“我是让服务员去炒菜了?还是让后厨直接面对顾客了?” 😉
MVP,MVC,MVVM三者做比
经过了上面酣畅淋漓的讲解MVP架构相信读者们一定对这个架构有了非常深的映像了,为了让这个架构能够真正的在你脑子烙下印子
我们接下来对另外两个主流架构(MVC架构,MVVM架构)做一个简单的比较。
先看他们三者的核心组件比较:
| 架构 | 核心组件 | 说明 |
|---|---|---|
| MVC | Controller | 类似角色,但 View 有时可直接读 Model(如模板引擎) |
| MVVM | ViewModel | 通过数据绑定自动同步,逻辑仍在 VM 中 |
| MVP | Presenter | 唯一协调者,View 完全被动 ← 最强调 P 的核心地位 |
再来他们三者的优劣势比较:
| 架构模式 | 优势 | 劣势 |
|---|---|---|
| MVC(Model-View-Controller) | • 结构简单,易于理解和实现 • 适合小型应用或团队熟悉该模式的场景 | • 控制器(Controller)易变得臃肿,难以维护 • 视图(View)与模型(Model)耦合度较高,不利于单元测试 |
| MVP(Model-View-Presenter) | • 视图与模型完全解耦,提升可测试性与可维护性 • Presenter 负责业务逻辑,使视图更轻量、职责更单一 | • 需额外编写 Presenter 层,代码量增加 • 对习惯 MVC 的团队而言,学习成本较高 |
| MVVM(Model-View-ViewModel) | • 通过数据绑定自动同步视图与视图模型,减少手动更新代码 • 视图模型(ViewModel)独立于 UI,便于测试和复用 • 特别适合高交互性的前端应用(如 WPF、Vue、Angular 等) | • 数据绑定机制增加了整体复杂度,初学者上手较慢 • 过度依赖绑定可能导致性能问题(如频繁触发更新或内存泄漏) |
结语
🌟MVP 架构,归根结底是一种让代码“各司其职、井然有序”的设计哲学。它用三块清晰的拼图——Model(数据与逻辑)、View(界面与交互)、Presenter(协调与决策)——把原本混乱的业务流程梳理成一条条可预测、可测试、可复用的流水线。
通过 “View 不碰 Model,Model 不知 View,所有交互经由 Presenter” 的强制隔离,我们不仅实现了高内聚低耦合,更构建了一个“前端专注展示,后端专注数据,中间层专注流程”的高效协作体系。
无论是开发一个简单的购物车功能,还是维护一个复杂的电商系统,MVP 都像一位冷静的“指挥家”,让每个组件在自己的轨道上精准运行。
当你下次面对一团乱麻的代码时,不妨问一句:“这是谁该干的事?”——答案或许就在 MVP 的三重结构里。
💡 学会 MVP,不是为了记住模式名称,而是学会如何写出更干净、更可控、更易扩展的代码。








