🔄 MVP 完整交互流程(与 MVC 关键区别)
🆚 MVC vs MVP 核心差异
关键环节 | MVC | MVP | 差异解析 |
---|---|---|---|
事件传递起点 | View → Controller | View → Presenter | ✅ 相同 |
Model 操作方 | Controller 直接修改 Model | Presenter 直接修改 Model | ✅ 相同 |
View 更新触发方 | Model 自动通知 View (观察者模式) | Presenter 主动调用 View 接口 | 🚨 最核心区别 |
View-Model 关系 | View 可直接监听 Model | View 和 Model 完全隔离 | 🚨 关键架构差异 |
数据获取方式 | View 直接从 Model 读取数据 | View 只能通过 Presenter 获取数据 | 🚨 重要区别 |
💡 MVP 的独特价值(通过代码说明)
场景:用户信息显示应用
# Model (不变)
class UserModel:def get_user(self) -> dict:return {"name": "Alice", "age": 30}# View 接口 (强制隔离)
class IUserView: # 🚩 MVP 核心:接口抽象def show_loading(self): passdef display_user(self, user: dict): passdef show_error(self, msg: str): pass# 具体 View 实现
class UserView(IUserView):def __init__(self, presenter):self.presenter = presenterself.btn = Button("加载用户", self.on_button_click) # UI 控件# 点击事件:仅传递,不做逻辑处理def on_button_click(self):self.presenter.load_user_data() # → 转交 Presenter# 以下实现接口方法(被动响应)def show_loading(self):print("加载中...")def display_user(self, user):print(f"姓名: {user['name']}, 年龄: {user['age']}")def show_error(self, msg):print(f"错误: {msg}")# Presenter (业务逻辑中心)
class UserPresenter:def __init__(self, view: IUserView):self.view = viewself.model = UserModel()def load_user_data(self):try:self.view.show_loading() # 主动控制UI状态user = self.model.get_user() # 操作Modelself.view.display_user(user) # 主动更新Viewexcept Exception as e:self.view.show_error(str(e)) # 主动处理错误
🧩 MVP 核心特点解析
-
View 的完全被动性
- View 只实现预定义接口 (如
IUserView
) - 不能直接访问 Model
- 不能自主更新 UI(必须等 Presenter 调用)
- View 只实现预定义接口 (如
-
Presenter 的绝对控制权
- 全权负责:
- 调用 Model 获取/修改数据
- 决定何时更新 View
- 错误处理/状态管理
# Presenter 控制完整流程 def load_user_data(self):self.view.show_loading() # 1. 控制UI状态data = self.model.get_data() # 2. 获取数据self.view.render(data) # 3. 更新UIself.log_analytics() # 4. 其他逻辑
- 全权负责:
-
测试优势的实际体现
# 测试 Presenter(无需真实 View 和 Model) class MockView(IUserView):def display_user(self, user):assert user["name"] == "Alice" # 验证逻辑正确性def test_presenter():view = MockView()presenter = UserPresenter(view)presenter.load_user_data() # 纯逻辑测试
🌟 为什么 MVP 比 MVC 更解耦?
场景 | MVC 实现 | MVP 实现 | MVP 优势 |
---|---|---|---|
更换数据源 | 需修改 View(监听新Model) | 仅修改 Presenter | ✅ 更少改动 |
同一逻辑支持多平台UI | View 包含平台相关代码 | 实现新 View 接口即可 | ✅ 复用核心 |
单元测试业务逻辑 | 需启动完整 MVC 环境 | 直接测试 Presenter + Mock View | ✅ 效率提升 |
典型案例:Android 从 MVC 转向 MVP/MVVM
旧问题:Activity 既当 View 又当 Controller → 代码臃肿难测试
解决方案:用 Presenter 剥离业务逻辑
💎 终极总结
模式 | 核心指令流 | 组件关系 | 适用场景 |
---|---|---|---|
MVC | View → Controller → Model → View | View 知道 Model | 简单应用/框架内置 |
MVP | View → Presenter → Model → Presenter → View | 双向隔离 | 高测试要求/复杂交互 |
简单记忆:
- MVC = “Model 推数据给 View”
- MVP = “Presenter 拉数据推给 View”