iOS设计模式之原型模式

514 阅读2分钟

定义

应用于复制(cloning)操作的模式成为原型模式(Protorype)。即对象实现copy方法,进行深拷贝,实现创建对象及引用资源的副本。

使用场景

使用原型模式的场景如下:

  • 需要创建的对象应独立于其类型与创建方式
  • 要实例化的类是在运行时决定的
  • 不想要与产品层次相对应的工厂层次
  • 不同类的实例间的差异仅是状态的若干组合
  • 类不容易创建,比如每个组件可发其他组件作为子节点的组合对象,或者应用资源相对较大的对象

有两种特别常用的情形:

  1. 有很多相关的类,其行为略有不同,而且主要差异在于内部属性,如名称,类型等。
  2. 需要使用组合(树形)对象作为其他东西的基础。

原型模式用到深拷贝方式,那么这里就要说一下深拷贝与浅拷贝的差异:

  • 浅拷贝:只复制指针而不是指针指向的地址。拷贝出来的对象指针与原对象不同,但是两个指针指向同一地址。即引用同一资源
  • 深拷贝:复制指针的同时,复制指针所指向的资源。实现完全的资源备份。生成内存中实际资源的真正副本。

Cocoa Touch框架为NSObject的派生类提供了实现深复制的协议--NSCopying协议及其方法-(id)copyWithZone:(NSZone *)zone。NSObject提供一个实例方法-(id)copy,默认调用copy方法调用[self copyWithZone:nil]。

对象如果需要实现原型模式,只需遵循NSCopying协议,并且实现-(id)copyWithZone:(NSZone *)zone方法,在方法中拷贝资源,返回副本。

代码实现

代码如下

@interface Stroke : NSObject <NSCopying>

@property (nonatomic, assign) CGPoint location;
@property (nonatomic, strong) UIColor *color;
@property (nonatomic, strong) NSArray <NSObject *> *subjects;

@end


@implementation Stroke

- (id)copyWithZone:(nullable NSZone *)zone{
    Stroke *strokeCopy = [[[self class] alloc] init];
    strokeCopy.location = self.location;
    strokeCopy.color = [self.color copy];
    NSMutableArray *mutableSubject = [@[] mutableCopy];
    for (NSObject *obj in self.subjects) {
        [mutableSubject addObject:[obj copy]];
    }
    strokeCopy.subjects = [mutableSubject copy];
    return strokeCopy;
}

@end

注意点:

  1. 赋值类似UIColor这种OC对象时,需要copy一份新的属性赋值
  2. 赋值NSArray这种集合类型的属性时,需要将其中的元素也copy一份