MVP分层架构模式深入剖析

MVP 完整交互流程(与 MVC 关键区别)

User View Presenter Model 点击按钮 通知事件 (如 on_button_click()) 请求数据变更 (如 set_data()) 返回操作结果 调用视图接口更新UI (如 update_ui(data)) 刷新界面 User View Presenter Model

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): pass
    def display_user(self, user: dict): pass
    def show_error(self, msg: str): pass

# 具体 View 实现
class UserView(IUserView):
    def __init__(self, presenter):
        self.presenter = presenter
        self.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 = view
        self.model = UserModel()
    
    def load_user_data(self):
        try:
            self.view.show_loading()  # 主动控制UI状态
            user = self.model.get_user()  # 操作Model
            self.view.display_user(user)  # 主动更新View
        except Exception as e:
            self.view.show_error(str(e))  # 主动处理错误

MVP 核心特点解析

  1. View 的完全被动性

    • View 只实现预定义接口 (如 IUserView)
    • 不能直接访问 Model
    • 不能自主更新 UI(必须等 Presenter 调用)
  2. 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. 更新UI
        self.log_analytics()           # 4. 其他逻辑
    
  3. 测试优势的实际体现

    # 测试 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”

你可能感兴趣的:(MVP分层架构模式深入剖析)