原型模式(Prototype Pattern)
2022-09-10 本文已影响0人
long弟弟
原型模式
意图:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
如果对象的创建成本比较大,而同一个类的不同对象之间差别不大(大部分字段都相同),在这种情况下,我们可以利用已有对象(原型)进行复制(或者叫拷贝)的方式来创建对象,以达到节省创建时间的目的。这种基于原型来创建对象的方式叫做原型设计模式,简称原型模式。

角色和职责
- Prototype
声明一个克隆自身的接口 - ConcretePrototype
实现一个克隆自身的操作 - Client
让一个原型克隆自身从而创建一个新的对象
拷贝的目的
产生一个副本对象,跟源对象互不影响。修改了源对象,不会影响副本对象;修改了副本对象,不会影响源对象。
copy、mutableCopy
- copy:不可变拷贝,产生不可变副本
- mutableCopy:可变拷贝,产生可变副本
原型模式的实现方式
- 深拷贝:内容拷贝,产生新的对象
- 浅拷贝:指针拷贝,没有产生新的对象
注:本文主要记录原型设计模式,完全拷贝
等相关概念自行学习了解!
原型模式的使用
一个复杂对象,具有自我复制功能,统一一套接口
系统提供的的类有的已经实现了NSCopying
协议
代码示例1
NSString *str1 = @"123";
NSString *str2 = [str1 copy]; //浅拷贝
//不可变源对象拷贝为不可变副本对象
NSLog(@"1:%p:%@", str1, str1);
NSLog(@"1:%p:%@", str2, str2);
str1 = @"456";
NSLog(@"2:%p:%@", str1, str1);
NSLog(@"2:%p:%@", str2, str2);
NSMutableString *str3 = [str1 mutableCopy];//深拷贝
//不可变源对象拷贝为可变副本对象
NSLog(@"3:%p:%@", str1, str1);
NSLog(@"3:%p:%@", str3, str3);
NSString *str4 = [str3 copy];//深拷贝
//可变源对象拷贝为不可变副本对象
NSLog(@"4:%p:%@", str3, str3);
NSLog(@"4:%p:%@", str4, str4);
NSMutableString *str5 = [str3 copy];//深拷贝
//可变源对象拷贝为可变副本对象
NSLog(@"5:%p:%@", str3, str3);
NSLog(@"5:%p:%@", str5, str5);
/*
1:0x100004018:123
1:0x100004018:123
2:0x100004058:456
2:0x100004018:123
3:0x100004058:456
3:0x1006067b0:456
4:0x1006067b0:456
4:0x5020a58dfd4e347d:456
5:0x1006067b0:456
5:0x5020a58dfd4e347d:456
*/
自定义的类实现原型模式
- 遵守
NSCopying
或NSMutableCopying
协议 - 实现协议中的方法
- (id)copyWithZone:(nullable NSZone *)zone;
或- (id)mutableCopyWithZone:(nullable NSZone *)zone;
代码示例2
#import <Foundation/Foundation.h>
@interface Person : NSObject ///<NSCopying>
@property (nonatomic, copy) NSString *name;
@end
@implementation Person
- (id)copyWithZone:(nullable NSZone *)zone {
Person *p = [[Person allocWithZone:zone] init];
p.name = self.name;
return p;
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *p1 = [[Person alloc] init];
p1.name = @"zs";
Person *p2 = [p1 copy];
NSLog(@"%p:%@", p1, p1);
NSLog(@"%p:%@", p2, p2);
NSLog(@"%@:%@", p1.name, p2.name);
}
return 0;
}
/*
0x101043970:<Person: 0x101043970>
0x10055af00:<Person: 0x10055af00>
zs:zs
*/