# MVC 与曲线案例:连接数据和界面 > 原书依据:第 20–21 章,印刷页 150–174,PDF 页 161–185。曲线应用位于印刷页 167–174。 Smalltalk-80 的 MVC 是桌面交互对象之间的协作。不要直接把 View、Controller 与 Web 请求处理器或某个现代框架组件一一等同。 ## 输入与职责 原书先介绍 `InputState` 与 `InputSensor`,再讨论 View、Controller 和 ControlManager。输入状态、输入读取和交互控制是相邻但不同的责任。 | 角色 | 保存或处理什么 | 对曲线应用的意义 | | --- | --- | --- | | Model | 应用数据与状态转换 | 曲线文本列表及当前选择 | | View | 读取模型并显示,管理视图几何 | 列表显示、曲线图形 | | Controller | 输入处理与操作协调 | 选择、菜单、编辑动作 | | ControlManager | 活动控制器的管理 | 协调窗口交互 | 一个模型可以有多个视图。视图和控制器组成显示与交互的配对关系;模型不需要直接包含像素绘制代码。 ## window 与 viewport 原书的 View 既有自身坐标范围,也有放到上层视图中的区域。曲线区域将数学坐标映射到窗口子区域,以便 y 轴向上,而屏幕坐标保持其约定。 调试错误显示时,先核对数据,再核对 window、viewport 和显示变换。模型数值正确不等于变换正确。 ## 曲线案例的对象结构 原书以 `CurveList` 继承 `OrderedCollection`,增加当前曲线选择;以 `CurveListView` 继承 `View`,重定义绘制行为。列表视图复用 SelectionInListView,并用选择子告诉它如何访问列表、读取选择、改变选择和取得菜单。 ```text 窗口 StandardSystemView ├─ 列表子视图 ──读写──→ CurveList └─ 曲线子视图 ──读取──→ 同一个 CurveList │ 状态变化通知 ↓ 更新依赖视图 ``` 类名在扫描 OCR 中存在大小写混淆,本文按语义统一写作 CurveList 和 CurveListView;安装原版代码前应以页面图像与镜像类名复核。 ## 追踪一次选择 1. 用户在列表中选择一条曲线。 2. 交互对象通过配置的选择子更新模型的当前选择。 3. 模型发送改变通知。 4. 依赖视图接收更新并重新读取模型。 5. 曲线视图清理绘制区域,将选择的文本求值为块。 6. 对采样点执行块,通过显示变换绘出折线。 这里“文本 → 块”是编译求值,不是普通数据解析。原书在可信镜像中演示原型编程;把这一机制用于接收外部输入的服务,需要另行设计输入语言与隔离策略。本文页面不执行用户代码。 ## 增删改也是模型转换 添加曲线会收集文本、追加列表、重置选择并通知;删除会移除当前项、清空选择并通知;修改会替换列表中的相应文本,再使显示更新。无选择时的菜单与有选择时不同。 这说明通知应该位于状态转换之后,让所有视图看到一致状态。曲线文本、当前选择与显示结果应作为三个不同层次检查。 ## 迁移设计思想 可以借鉴的组织方式是:将领域状态集中在模型,让输入动作调用明确的状态转换,由订阅者负责刷新显示。原书具体的窗口类、编译器调用和采样算法仍属于历史实现。本教程没有复原完整 GUI 程序或声称它已在当代实现中运行。