三种常见设计模式:MVC-Delegate-Target-Action

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)。

数据流向:

  1. 用户操作 View (e.g., 点击刷新按钮)。
  2. View 通知 Controller 这个事件。
  3. Controller 调用 Model 去获取新数据 (e.g., productService.getNewProducts())。
  4. Model 返回新数据给 Controller。
  5. 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);

工作流程:

  1. 签约 :控制器告诉列表 tableView.delegate = self (我来当你的代理)。
  2. 事件发生:用户点击了列表的某一行。
  3. 通知代理:列表(委托方)检查它的代理(控制器)是否实现了"被点击"这个合同方法。
  4. 执行工作:如果实现了,列表就调用控制器里的那个方法,并把点击的行号等信息传过去,让控制器完成后续的业务逻辑(如页面跳转)。

关键点: 实现了对象间的解耦,让一个通用组件(如列表)可以被用在任何业务场景中。


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)。