原型模式(prototype):用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
优点:
1、原型模式其实就是从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节。
2、隐藏了创建细节,也提高了创建对象的性能。
缺点:
1、在实现深克隆的时候可能需要比较复杂的代码。
2、需要为每一个类配备一个克隆方法,而且这个克隆方法需要对类的功能进行通盘考虑,这对全新的类来说不是很难,但对已有的类进行改造时,不一定是件容易的事,必须修改其源代码,违背了“开闭原则”。
总结:
1、原型模式向客户隐藏了创建对象的复杂性。客户只需要知道要创建对象的类型,然后通过请求就可以获得和该对象一模一样的新对象,无须知道具体的创建过程。
2、克隆分为浅克隆和深克隆两种。
3、我们虽然可以利用原型模式来获得一个新对象,但有时对象的复制可能会相当的复杂,比如深克隆。
项目地址:https://github.com/GameRisker/Study-Design-Patterns.git
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
// // main.m // ProtoType // // Created by GameRisker on 16/1/10. // Copyright (c) 2016年 GameRisker. All rights reserved. // #import "Resume.h" #import <Foundation/Foundation.h> int main(int argc, const char *argv[]) { @autoreleasepool { // insert code here... Resume *resume1 = [[Resume alloc] initWithName:@"GAMERISKER_NAME_1"]; [resume1 SetPersonalInfo:@"BOY" age:@"30"]; [resume1 SetWrokExperience:@"100-200" company:@"GAMERISKER_1"]; NSLog(@"Retain count is %ld", CFGetRetainCount((__bridge CFTypeRef)resume1)); Resume *resume2 = [resume1 copy]; [resume2 SetWrokExperience:@"200-300" company:@"GAMERISKER_2"]; NSLog(@"Retain count is %ld", CFGetRetainCount((__bridge CFTypeRef)resume2)); Resume *resume3 = [resume1 copy]; [resume3 SetPersonalInfo:@"BOY" age:@"30"]; [resume3 SetWrokExperience:@"300-400" company:@"GAMERISKER_3"]; NSLog(@"Retain count is %ld", CFGetRetainCount((__bridge CFTypeRef)resume3)); [resume1 Display]; [resume2 Display]; [resume3 Display]; } return 0; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// // WorkExperience.h // // // Created by GameRisker on 16/1/10. // // #import <Foundation/Foundation.h> @interface WorkExperience : NSObject <NSCopying> @property(strong, nonatomic) NSString *workData; @property(strong, nonatomic) NSString *company; @end |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
// // WorkExperience.m // // // Created by GameRisker on 16/1/10. // // #import "WorkExperience.h" @implementation WorkExperience - (id)copyWithZone:(NSZone *)zone { WorkExperience *newWrok = [[self class] allocWithZone:zone]; newWrok.workData = [self.workData copy]; newWrok.company = [self.company copy]; return newWrok; } @end |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
// // Resume.h // // // Created by GameRisker on 16/1/10. // // #import "WorkExperience.h" #import <Foundation/Foundation.h> @interface Resume : NSObject <NSCopying> @property(strong, nonatomic) NSString *name; @property(strong, nonatomic) NSString *sex; @property(strong, nonatomic) NSString *age; @property(strong, nonatomic) WorkExperience *work; - (instancetype)initWithName:(NSString *)newName; - (void)SetPersonalInfo:(NSString *)sex age:(NSString *)age; - (void)SetWrokExperience:(NSString *)workData company:(NSString *)company; - (void)Display; @end |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
// // Resume.m // // // Created by GameRisker on 16/1/10. // // #import "Resume.h" @implementation Resume - (instancetype)initWithName:(NSString *)newName { if (self = [super init]) { self.name = newName; self.work = [[WorkExperience alloc] init]; } return self; } - (void)SetPersonalInfo:(NSString *)sex age:(NSString *)age { self.sex = sex; self.age = age; } - (void)SetWrokExperience:(NSString *)workData company:(NSString *)company { self.work.workData = workData; self.work.company = company; } - (void)Display { NSLog(@"i called the %@ , i was a %@ , %@ years old!", self.name, self.age, self.age); NSLog(@"work experience : %@ %@", self.work.workData, self.work.company); } - (id)copyWithZone:(NSZone *)zone { Resume *newResume = [[[self class] allocWithZone:zone] init]; [newResume setName:[self.name copy]]; [newResume SetPersonalInfo:[self.sex copy] age:[self.age copy]]; [newResume setWork:[self.work copy]]; return newResume; } @end |