表述 (创建型模式)
用原型实例指定创建对象的种类,并通过复制这个原型创建新的对象
这里的复制指深复制 关于深浅复制传送门 深复制就是开辟新内存实现真正的内存复制 浅复制, 只复制指针, 堆内存不变.
原型模式类图
原型模式类图
- Prototype(原型类):声明一个拷贝自身的接口
- ConcretePrototype1和ConcretePrototype2:为Prototype的子类,实现自身的clone方法
优点
简化对象的创建,把创建的过程封闭到对象的内部
使用场景
- 需要创建的对象应独立于其类型与创建方式(想要的对象并不能够直接通过初始化函数来创建出来,其创建过程不具有普遍性且复杂)
- 要实例化类是在运行时决定的(在编写代码的时候并不知道哪种对象会被创建出来,其内部的结构如何复杂
- 不想要与产品层次相对应的工厂层次(不通过工厂方法或者抽象工厂来控制产品的创建过程,想要直接复制对象)
- 有很多的相关的类,其行为略有不同,而且主要差异在于内部属性,如名称等
- 类不容易创建,比如每个组件可把其他组件作为子节点的组合对象。复制已有的组合对象并对副本进行修改会更加容易。如果内部结构复杂,不容易重现
示例
需求:要求有个人信息类,必须有姓名和年龄,最终需要三份个人信息
代码语言:javascript复制class Info {
var name : String
var age : Int
init(name:String,age:Int) {
self.name = name
self.age = age
}
func show() {
print("name:(name),age:(age)")
}
}
let info0 = Info.init(name: "小白",age: 18)
info0.show() //name:小白,age:18
let info1 = Info.init(name: "小白",age: 18)
info1.show() //name:小白,age:18
let info2 = Info.init(name: "小白",age: 18)
info2.show() //name:小白,age:18
可以看到三份信息需要实例化三次,如果是要n份,就需要实例化n次,这显然不是希望的样子
iOS中,采纳NSCopying协议,通过这个协议来实现对象的深拷贝
代码语言:javascript复制class Info : NSCopying {
var name : String
var age : Int
init(name:String,age:Int) {
self.name = name
self.age = age
}
func show() {
print("name:(name),age:(age)")
}
func copy(with zone: NSZone? = nil) -> Any {
return Info (name: name, age: age)
}
}
let info0 = Info.init(name: "小白",age: 18)
info0.show() //name:小白,age:18
let info1 = info0.copy() as! Info
info1.show() //name:小白,age:18
let info2 = info0.copy() as! Info
info2.show() //name:小白,age:18