当前位置: 首页 > backend >正文

MVC分层架构模式深入剖析

在这里插入图片描述

🔄 MVC 交互流程

User View Controller Model 点击按钮 调用Controller方法(如onButtonClick()) 修改数据(如model.setData()) 自动通知更新(通过观察者模式) 刷新UI User View Controller Model

💡 核心原则:View 的“被动性”

  1. View 只做两件事

    • 展示 UI 元素(按钮、文本框等)
    • 将用户事件转交给 Controller(自身不处理业务逻辑)
  2. Controller 是真正的决策者

    • 决定如何响应事件
    • 操作 Model 修改数据
    • 触发 View 更新(或由 Model 自动触发)

🧩 代码示例:PyQt 中的 MVC 实现

# Model(数据层)
class CounterModel:def __init__(self):self.value = 0self.observers = []  # 观察者列表(View)def add_observer(self, observer):self.observers.append(observer)def increment(self):self.value += 1# 数据变更后通知所有观察者(View)for observer in self.observers:observer.update(self.value)# View(界面层)
class CounterView(QWidget):def __init__(self, controller):super().__init__()self.controller = controllerself.label = QLabel("0")button = QPushButton("点击+1")# 关键点:View 捕获点击事件,但立刻转交给 Controllerbutton.clicked.connect(self.controller.handle_button_click)  layout = QVBoxLayout()layout.addWidget(self.label)layout.addWidget(button)self.setLayout(layout)def update(self, value):  # 被Model调用self.label.setText(str(value))# Controller(逻辑层)
class CounterController:def __init__(self):self.model = CounterModel()self.view = CounterView(self)self.model.add_observer(self.view)  # 注册View为观察者def handle_button_click(self):# View 点击事件最终由 Controller 处理self.model.increment()  # 修改Model# 主程序
app = QApplication([])
controller = CounterController()
controller.view.show()
app.exec_()

❓ 为什么不是 View 直接调用 Model?

若允许 View 直接操作 Model:

# 错误示例(违反 MVC)
class BadView(QWidget):def __init__(self, model):...button.clicked.connect(model.increment)  # View 直接调用 Model

会导致:

  1. 紧耦合:更换 Model 需修改 View 代码
  2. 无法复用:该 View 只能搭配特定 Model
  3. 测试困难:需启动完整 UI 才能测试逻辑

✅ MVC 的正确分工总结

组件职责
View1. 渲染界面
2. 转发用户事件 → Controller
Controller1. 接收 View 事件
2. 调用 Model 修改数据
3. 协调更新流程
Model1. 存储数据/逻辑
2. 数据变更后通知 View(观察者模式)

简单记忆:View 是秘书(只传递文件),Controller 是经理(做决策),Model 是仓库(保管数据)

http://www.xdnf.cn/news/12667.html

相关文章:

  • 2025年—Comfyui聚合插件:Comfyui-LayerStyle 超多实用功能 | 附各功能模型
  • 【R语言编程——数据调用】
  • SpringBoot-17-MyBatis动态SQL标签之常用标签
  • 【MySQL】10.事务管理
  • C++刷题:日期模拟(1)
  • 使用 C++/OpenCV 创建动态流星雨特效 (实时动画)
  • Linux 系统中的算法技巧与性能优化
  • 浅谈 React Hooks
  • 行为型设计模式之Interpreter(解释器)
  • 低功耗MQTT物联网架构Java实现揭秘
  • 八、【ESP32开发全栈指南:UDP客户端】
  • NLP学习路线图(三十):微调策略
  • Python图论与网络可视化——网络结构、路径分析与生物代谢通路
  • 【Linux shell】shell中的变量——构建脚本逻辑的基石
  • 水利工程流速监测中的雷达流速仪
  • FreeRTOS事件组-笔记
  • 33、原子操作
  • C++常用的自动化测试库
  • PostgreSQL数据类型使用
  • 【生活】程序员防猝si指南
  • java_网络服务相关_gateway_nacos_feign区别联系
  • JAVA-springboot log日志
  • 打卡46天
  • DDPM优化目标公式推导
  • JAVA国际版二手交易系统手机回收好物回收发布闲置商品系统源码支持APP+H5
  • 每日算法刷题Day25 6.7:leetcode二分答案3道题,用时1h40min(遇到两道动态规划和贪心时间较长)
  • 【Go语言基础【15】】数组:固定长度的连续存储结构
  • FreeRTOS任务之深入篇
  • ps蒙版介绍
  • Mac软件卸载指南,简单易懂!