原型模式(Prototype pattern):

  定义:使用原型实例指定创建对象的种类,并通过复制这个原型创建对象。也可以理解为模板,在创建新对象的时候,按照模板的方法来复制,避免重复造轮子。

  简单来说,就是根据这个原型创建新的对象,而且不需要知道任何创建的细节。例如,在生物学中,有“细胞分裂”,细胞在一定条件下从一个分裂成两个,再由 2 个分裂成 4 个.......。分裂出来的细胞是基于原始的细胞(原型),这种原始的细胞决定了分裂出来的细胞结构。这种分裂过程,称为“原型模式”。在 TableViewCell 重用机制中,也可以理解为使用原型模式,使用 cell 模板来复制 cell。

  UML 图如下:

  iOS 开发之 设计模式【一】原型模式 (Prototype pattern)-LMLPHP

  应用场景:

    当一个类的组成比较复杂时,例如包含多个组件或自定义属性时,可以直接复制当前对象;

    当对象间的区别不大时,只有几个属性不同,可以考虑使用原型模式。

  优点:使用原型模式可以避免内存较大开销的初始化创建动作。不用重新初始化对象,而是动态的获取对象运行时的状态。  

  

  实现:

  在 iOS 中使用原型模式,在多数情况下属于深拷贝的行为,需要遵循 NSCoding 协议。

  深拷贝(mutableCopy):开辟内存,实现真正的内存复制;即拷贝后对象值相同,但地址不同。

  浅拷贝(Copy):只复制指针,堆内存不变。即拷贝后对象值相同,地址也相同。只复制了指针值,并没有复制指针指向的资源(即没有创建指针指向资源的副本),复制后原有指针和新指针共享同一块内存。

  对于系统中已经实现的同时支持NSCopying协议和NSMutableCopying协议的NSString、NSDictionary等,copy总是返回不可变副本,mutableCopy总是返回可变副本。

  iOS 开发之 设计模式【一】原型模式 (Prototype pattern)-LMLPHP

  对于浅拷贝,想要使用 copy,需要遵守 NSCopying 协议,并且实现 copyWithZone: 方法。

  对于深拷贝,想要使用 mutableCopy,需要遵守 NSMutableCopying 协议,并且实现 mutableCopyWithZone: 方法。

/** Prototype Pattern 原型模式 **/
PrototypePerson *person = [[PrototypePerson alloc] init];
person.name = @"张三";
person.gender = PrototypeGenderMale;
person.age = ;
person.height = 176.4; //深拷贝
PrototypePerson *person1 = [person copy];
NSLog(@"deepCopy name = %@ age = %lu", person1.name, person1.age);
//浅拷贝
PrototypePerson *person2 = person;
NSLog(@"shallowCopy name = %@ age=%lu", person2.name, person2.age);
person2.name = @"李四";
person2.age = ;
NSLog(@"deepCopy person1 name = %@ age = %lu", person1.name, person1.age);
NSLog(@"shallowCopy person name = %@ age = %lu", person.name, person.age);

  iOS 开发之 设计模式【一】原型模式 (Prototype pattern)-LMLPHP

  根据结果可知,对于浅拷贝的对象,改变对象值,影响原型,而不对深拷贝的值有影响

  代码链接:https://github.com/zhangtibin/DesignModelProject

05-11 13:51