原型设计模式(Prototype)
原型模式是创建型设计模式,也是 iOS 开发中最简单、最实用的设计模式之一。
一、核心定义
一句话总结:通过克隆(复制)已有的原型对象,快速创建一个属性相同、相互独立的新对象,不通过传统初始化(init)创建。
通俗比喻:你有一份填好的完美表格(原型对象),不用重新手写一份,直接复印出一模一样的新表格(克隆对象),复印稿和原稿互不影响。
核心解决的痛点:
- 创建复杂/配置繁琐的对象时,避免重复初始化;
- 防止修改原对象,保证数据安全;
- https://www.iqiyi.com/v_27vhvdkoc34.html
https://www.iqiyi.com/v_2eo5elqbj3w.html
https://www.iqiyi.com/v_2d26dzszu9w.html
https://www.iqiyi.com/v_msitceusus.html - 提升对象创建效率(克隆比
init快很多)。
UML图
- 原型 (Prototype) 接口将对克隆方法进行声明。 在绝大多数情况下, 其中只会有一个名为 clone克隆的方法。
- 具体原型 (Concrete Prototype) 类将实现克隆方法。 除了将原始对象的数据复制到克隆体中之外, 该方法有时还需处理克隆过程中的极端情况, 例如克隆关联对象和梳理递归依赖等等。
- 客户端 (Client) 可以复制实现了原型接口的任何对象
二、iOS 核心知识点:浅拷贝 vs 深拷贝
原型模式的本质就是对象拷贝,iOS 中分为两种拷贝方式,这是必须掌握的核心:
| 类型 | 含义 | 内存表现 | 适用场景 |
|---|---|---|---|
| 浅拷贝(Shallow Copy) | 只拷贝对象本身,对象内部的引用类型成员共用同一块内存 | 新对象 ≠ 原对象,但内部引用属性指向同一个 | 简单对象、无嵌套引用类型 |
| 深拷贝(Deep Copy) | 拷贝对象本身 +递归拷贝所有嵌套的引用类型成员 | 新对象和原对象完全独立,无共享内存 | 复杂对象、嵌套模型、需要完全隔离的场景 |
✅ iOS 规则:
- Swift 结构体(struct):值类型,默认深拷贝;
- Swift 类(class):引用类型,必须手动实现深拷贝;
- OC:通过
NSCopying协议实现拷贝。
三、iOS 原生支持
苹果官方直接为原型模式提供了原生接口,开箱即用:
- OC:
NSCopying/NSMutableCopying协议 +copy/mutableCopy方法; - https://www.iqiyi.com/v_pjedruiaq0.html
https://www.iqiyi.com/v_e9rp64td5g.html
https://www.iqiyi.com/v_1gvhadgh9s0.html - Swift:自定义
Copyable协议,实现copy()方法。
四、iOS 开发实战场景
这些场景你每天都可能用到,只是没意识到是原型模式:
1. 编辑页数据隔离
场景:用户进入个人资料编辑页,不能直接修改原数据,防止取消编辑后数据错乱。
方案:克隆原用户模型 → 修改克隆对象 → 保存时才替换原对象。
2. 复杂对象快速复用
场景:网络请求、配置文件、UI 样式等初始化成本高的对象。
方案:创建一个原型配置 → 克隆复用,不用重复写参数。
3. 大量相似对象创建
场景:列表模型、游戏角色、自定义控件批量生成。
方案:克隆原型对象,比init初始化效率更高。
4. 撤销/重做(Undo/Redo)
场景:笔记、绘图、表单编辑的撤销功能。
方案:克隆对象状态,保存历史记录。
5. 缓存对象复用
场景:缓存的商品、主题、UI 组件,直接克隆使用。
五、Swift 代码实战
场景 1:基础深拷贝
针对类(引用类型)实现完整的原型模式:
// 1. 定义原型协议 protocol Prototype { func clone() -> Self } // 2. 复杂业务模型(用户模型) class UserModel: Prototype { let name: String var age: Int // 嵌套引用类型(深拷贝关键) var address: AddressModel init(name: String, age: Int, address: AddressModel) { self.name = name self.age = age self.address = address } // 3. 实现深拷贝 func clone() -> UserModel { // 递归克隆嵌套对象 let newAddress = address.clone() return UserModel(name: name, age: age, address: newAddress) } } // 嵌套模型也实现原型 class AddressModel: Prototype { var city: String init(city: String) { self.city = city } func clone() -> AddressModel { AddressModel(city: city) } } // 4. 使用:原型模式创建对象 // 原始对象(原型) let originalUser = UserModel(name: "张三", age: 20, address: AddressModel(city: "北京")) // 克隆新对象(核心!) let cloneUser = originalUser.clone() // 修改克隆对象,不影响原对象 cloneUser.age = 25 cloneUser.address.city = "上海" print(originalUser.age, originalUser.address.city) // 20 北京(原对象不变) print(cloneUser.age, cloneUser.address.city) // 25 上海(新对象独立)场景 2:极简写法(Struct 值类型)
Swift 结构体天生支持原型模式,无需额外代码:
struct ProductModel { var name: String var price: Double } // 原型对象 let original = ProductModel(name: "iPhone", price: 5999) // 直接拷贝 = 原型模式 let clone = original六、原型模式 vs 其他创建型模式(快速区分)
| 模式 | 核心逻辑 | 适用场景 |
|---|---|---|
| 原型模式 | 克隆现有对象 | 复杂/已配置对象、需要数据隔离 |
| 简单工厂 | 统一创建新对象 | 简单固定对象 |
| 工厂方法 | 子类工厂创建对象 | 频繁扩展的对象 |
| 生成器模式 | 分步配置创建对象 | 多参数、链式配置 |
总结
原型模式 = 对象克隆
- 是 iOS 开发最简单、最实用的创建型模式;
- 核心价值:快速创建独立对象,保护原数据不被修改;
- Swift 进阶:struct 默认深拷贝,class 需手动实现
clone(); - 黄金场景:编辑页数据隔离、复杂对象复用、列表模型创建。