1. MVC (Model-View-Controller) - 【架构模式】
一句话概括: 将 App 的代码职责划分成三个独立的部分,实现"业务逻辑"和"用户界面"的分离。
| 角色 | iOS 中的典型代表 | 职责 | 后端类比 |
|---|---|---|---|
| Model (模型) | struct User, class Product |
存储和管理数据;定义业务规则(如密码格式验证)。它完全不关心数据如何展示。 | POJO / Entity / DTO 例如 User.java,只包含字段和 getter/setter,以及一些业务验证方法。 |
| View (视图) | UIView, UILabel, UIButton |
展示数据 给用户看;接收用户的原始输入(如点击、滑动)。它完全不关心数据从哪来,也不处理业务逻辑。 | HTML / JSP / Thymeleaf 模板 它只负责渲染数据,本身不生产数据。 |
| Controller (控制器) | UIViewController |
核心协调者。从 Model 获取数据,处理后交给 View 显示;接收 View 的用户事件,调用 Model 更新数据。 | Controller / Service 层 例如 Spring 的 @RestController,它接收 HTTP 请求,调用 Service 处理业务,从数据库拿到 Model,最后把 Model 组装成 JSON 返回给前端(View)。 |
数据流向:
- 用户操作 View (e.g., 点击刷新按钮)。
- View 通知 Controller 这个事件。
- Controller 调用 Model 去获取新数据 (e.g.,
productService.getNewProducts())。 - Model 返回新数据给 Controller。
- Controller 更新 View,把新数据显示出来。
关键点: Model 和 View 永远不直接通信。
2. Delegate (委托/代理) - 【对象间通信模式】
一句话概括: 一个对象(委托方 )把一些自己不想或不能处理的工作,外包给另一个对象(代理方)来完成。
后端类比: 这就是回调接口 (Callback Interface)。
| 角色 | 例子 | 职责 | 后端类比 |
|---|---|---|---|
| 委托方 (Delegator) | UITableView |
一个通用的列表视图。它知道何时被滚动、何时某一行被点击,但它不知道点击后具体该做什么。 | 一个通用的事件处理器,如消息队列的消费者框架。它只负责从队列里取消息,但不知道如何处理这条消息。 |
| 代理方 (Delegate) | UIViewController |
你的控制器。它最清楚点击了"用户A"这一行后,应该跳转到用户A的详情页。 | 你自己写的业务逻辑实现类 ,它实现了消息处理的接口 MessageHandler,并重写了 onMessage(Message msg) 方法。 |
| 协议 (Protocol) | UITableViewDelegate |
一份"外包合同 "。合同里规定了代理方必须或可以选择实现 哪些方法,如 tableView(_:didSelectRowAt:) (某行被选中时调用)。 |
接口定义 ,如 interface MessageHandler,里面定义了 void onMessage(Message msg);。 |
工作流程:
- 签约 :控制器告诉列表
tableView.delegate = self(我来当你的代理)。 - 事件发生:用户点击了列表的某一行。
- 通知代理:列表(委托方)检查它的代理(控制器)是否实现了"被点击"这个合同方法。
- 执行工作:如果实现了,列表就调用控制器里的那个方法,并把点击的行号等信息传过去,让控制器完成后续的业务逻辑(如页面跳转)。
关键点: 实现了对象间的解耦,让一个通用组件(如列表)可以被用在任何业务场景中。
3. Target-Action (目标-动作) - 【对象间通信模式】
一句话概括: 当某个事件发生时,去调用某个目标 (Target) 对象上的某个动作 (Action) 方法。
后端类比: 非常像反射 (Reflection) 调用,或者一个配置好的消息路由。
工作流程(以按钮点击为例):
button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
这行代码就是一个完整的路由配置:
for: .touchUpInside(事件 Event): 当"点击"事件发生时...target: self(目标 Target) : ...找到self(当前控制器) 这个对象...action: #selector(buttonTapped)(动作 Action) : ...调用它身上名字叫buttonTapped的方法。
与 Delegate 的区别:
- 关系松散:Target-Action 更加松散。一个对象可以成为多个事件的 Target,一个事件也可以通知多个 Target-Action 对。
- 关系正式:Delegate 是一种更正式、一对一的"外包"关系,并且有"合同"(Protocol)来约束。
- 安全性 :Delegate 更安全,因为"合同"在编译时会被检查。Target-Action 依赖的方法名(
#selector)如果写错,编译时不会报错,运行时才会闪退(在 Objective-C 中)。
关键点: 这是处理简单、一次性事件响应的绝佳方式,尤其适用于按钮、滑块等 UI 控件。
总结速记表
| 模式 | 核心思想 | 解决什么问题 | 记忆口诀 |
|---|---|---|---|
| MVC | 职责分离 | App 整体代码的组织和结构。 | "包工头" (Controller) 协调 "数据源" (Model) 和 "装修队" (View)。 |
| Delegate | 工作外包 | 一个通用对象如何将特定业务逻辑交给另一个对象处理。 | "外包合同",规定了代理需要做什么。 |
| Target-Action | 事件路由 | 一个简单的事件(如点击)如何触发一个具体的方法。 | "定时闹钟" ,时间到了 (Event),就去叫醒某人 (Target),让他做某事 (Action)。 |