使用Object-C实现23种设计模式之原型模式
2016-05-24 21:07
453 查看
今天讲解一下最后一个创建型模式——原型模式,在讲解原型模式之前,先说两个概念,深拷贝和浅拷贝,相信学过C或者C++的人都应该了解什么是深拷贝什么是浅拷贝。
深拷贝:增加一个指针并且指向一个新的内存空间,使新的内存空间内存储的数据与被拷贝对象的数据相同。
浅拷贝:增加一个指针只想被拷贝的对象。
下面举一个特别通俗的例子:某农夫家有两个儿子,该农夫给大儿子买了一套房子,二儿子也想要同样的房子,于是农夫又买下一套构造一样的房子,并且把内部装修的跟大儿子的房子一模一样后,给了二儿子,这就是深拷贝;同样的示例,农夫给大儿子买房子后,二儿子想要同样的房子,但是农夫资金不足,就给二儿子配了一把大儿子家房子的钥匙,给了二儿子,这就是浅拷贝。
彻底了解深拷贝与浅拷贝之后,再去学习下面的原型模式:
所谓原型模式,就是根据一个对象创建一个相同的对象,这样的好处是,在创建对象是,节省了很多对对象的属性进行初始化的过程,在很大程度上提高了代码质量以及开发效率。
此外,原型模式很少单独出现,他的出现一般伴随着其他的设计模式,然而,原型模式与单例模式在实现上又有着冲突,所以,两者不可能同时出现。
首先,看下面一个实例:
在某高中男生宿舍中,有四个人,二者四个人恰恰是四胞胎(举例需求,如有雷同,纯属巧合>-<),死人无论在身高、体重等方面,不尽相同,再次,假设死人名字分别为张一,张二,张三,张四,家庭地址为山东省,性别均为男,下面构建一个Person类,假设其只有姓、名、性别、家庭住址四个属性。
Person.h
Person.m
这里的关键是实现NSCopying协议,以及对协议中copyWithZone方法的实现。
下面看一下使用原型模式的好处,如果不使用原型模式,则创建者兄弟四人具体实例的过程应如下所示:
输出结果为:
2016-05-24 21:05:01.511 设计模式之五原型模式[860:29812]内存地址:<Person:
0x1004001e0>姓:张名:一性别:男地址:山东省
2016-05-24 21:05:01.511 设计模式之五原型模式[860:29812]内存地址:<Person:
0x100400380>姓:张名:二性别:男地址:山东省
2016-05-24 21:05:01.511 设计模式之五原型模式[860:29812]内存地址:<Person:
0x1004003b0>姓:张名:三性别:男地址:山东省
2016-05-24 21:05:01.512 设计模式之五原型模式[860:29812]内存地址:<Person:
0x1004003e0>姓:张名:四性别:男地址:山东省
Program ended with exit code: 0
现在这个实例中只涉及了四个属性,偿若某一对象包含上百个属性之后,可想而知使用这种低质量代码的复杂程度,而使用原型模式之后,则变得相当轻松:
输出结果如下:
2016-05-24 22:08:59.949 设计模式之五原型模式[980:44674]内存地址:<Person:
0x100103a80>姓:张名:一性别:男地址:山东省
2016-05-24 22:08:59.950 设计模式之五原型模式[980:44674]内存地址:<Person:
0x100105b90>姓:张名:二性别:男地址:山东省
2016-05-24 22:08:59.950 设计模式之五原型模式[980:44674]内存地址:<Person:
0x100105bc0>姓:张名:三性别:男地址:山东省
2016-05-24 22:08:59.950 设计模式之五原型模式[980:44674]内存地址:<Person:
0x100105bf0>姓:张名:四性别:男地址:山东省
Program ended with exit code: 0
可以看到,两次输出结果除内存地址(内存地址由运行时系统自动分配)外,完全相同。且使用原型模式后,只需要根据现有对象进行copy,创建出一个新的对象,将新对象中个别不同于原对象的属性更改即可。
以上为我个人对原型模式的简单理解,如有不到之处,敬请指正。
未完待续。。。
深拷贝:增加一个指针并且指向一个新的内存空间,使新的内存空间内存储的数据与被拷贝对象的数据相同。
浅拷贝:增加一个指针只想被拷贝的对象。
下面举一个特别通俗的例子:某农夫家有两个儿子,该农夫给大儿子买了一套房子,二儿子也想要同样的房子,于是农夫又买下一套构造一样的房子,并且把内部装修的跟大儿子的房子一模一样后,给了二儿子,这就是深拷贝;同样的示例,农夫给大儿子买房子后,二儿子想要同样的房子,但是农夫资金不足,就给二儿子配了一把大儿子家房子的钥匙,给了二儿子,这就是浅拷贝。
彻底了解深拷贝与浅拷贝之后,再去学习下面的原型模式:
所谓原型模式,就是根据一个对象创建一个相同的对象,这样的好处是,在创建对象是,节省了很多对对象的属性进行初始化的过程,在很大程度上提高了代码质量以及开发效率。
此外,原型模式很少单独出现,他的出现一般伴随着其他的设计模式,然而,原型模式与单例模式在实现上又有着冲突,所以,两者不可能同时出现。
首先,看下面一个实例:
在某高中男生宿舍中,有四个人,二者四个人恰恰是四胞胎(举例需求,如有雷同,纯属巧合>-<),死人无论在身高、体重等方面,不尽相同,再次,假设死人名字分别为张一,张二,张三,张四,家庭地址为山东省,性别均为男,下面构建一个Person类,假设其只有姓、名、性别、家庭住址四个属性。
Person.h
#import <Foundation/Foundation.h> @interface Person : NSObject<NSCopying> @property (nonatomic) NSString* firstName; @property (nonatomic) NSString* lastName; @property (nonatomic) NSString* sex; @property (nonatomic) NSString* address; -(id)initWithFirstName:(NSString*)firstName andLastName:(NSString*)lastName andSex:(NSString*)sex andAddress:(NSString*)address; @end
Person.m
#import "Person.h" @implementation Person @synthesize firstName = _firstName; @synthesize lastName = _lastName; @synthesize sex = _sex; @synthesize address = _address; -(id)initWithFirstName:(NSString *)firstName andLastName:(NSString *)lastName andSex:(NSString *)sex andAddress:(NSString *)address{ if(self = [super init]){ _firstName = firstName; _lastName = lastName; _sex = sex; _address = address; } return self; } -(id)copyWithZone:(NSZone *)zone{ Person* per = [[[self class]allocWithZone:zone]initWithFirstName:_firstName andLastName:_lastName andSex:_sex andAddress:_address]; return per; } @end
这里的关键是实现NSCopying协议,以及对协议中copyWithZone方法的实现。
下面看一下使用原型模式的好处,如果不使用原型模式,则创建者兄弟四人具体实例的过程应如下所示:
#import <Foundation/Foundation.h> #import "Person.h" int main(int argc, const char * argv[]) { @autoreleasepool { Person* per1 = [[Person alloc]initWithFirstName:@"张" andLastName:@"一" andSex:@"男" andAddress:@"山东省"]; Person* per2 = [[Person alloc]initWithFirstName:@"张" andLastName:@"二" andSex:@"男" andAddress:@"山东省"]; Person* per3 = [[Person alloc]initWithFirstName:@"张" andLastName:@"三" andSex:@"男" andAddress:@"山东省"]; Person* per4 = [[Person alloc]initWithFirstName:@"张" andLastName:@"四" andSex:@"男" andAddress:@"山东省"]; NSLog(@"内存地址:%@ 姓:%@ 名:%@ 性别:%@ 地址:%@",per1,per1.firstName,per1.lastName,per1.sex,per1.address); NSLog(@"内存地址:%@ 姓:%@ 名:%@ 性别:%@ 地址:%@",per2,per2.firstName,per2.lastName,per2.sex,per2.address); NSLog(@"内存地址:%@ 姓:%@ 名:%@ 性别:%@ 地址:%@",per3,per3.firstName,per3.lastName,per3.sex,per3.address); NSLog(@"内存地址:%@ 姓:%@ 名:%@ 性别:%@ 地址:%@",per4,per4.firstName,per4.lastName,per4.sex,per4.address); } return 0; }
输出结果为:
2016-05-24 21:05:01.511 设计模式之五原型模式[860:29812]内存地址:<Person:
0x1004001e0>姓:张名:一性别:男地址:山东省
2016-05-24 21:05:01.511 设计模式之五原型模式[860:29812]内存地址:<Person:
0x100400380>姓:张名:二性别:男地址:山东省
2016-05-24 21:05:01.511 设计模式之五原型模式[860:29812]内存地址:<Person:
0x1004003b0>姓:张名:三性别:男地址:山东省
2016-05-24 21:05:01.512 设计模式之五原型模式[860:29812]内存地址:<Person:
0x1004003e0>姓:张名:四性别:男地址:山东省
Program ended with exit code: 0
现在这个实例中只涉及了四个属性,偿若某一对象包含上百个属性之后,可想而知使用这种低质量代码的复杂程度,而使用原型模式之后,则变得相当轻松:
#import <Foundation/Foundation.h> #import "Person.h" int main(int argc, const char * argv[]) { @autoreleasepool { Person* per1 = [[Person alloc]initWithFirstName:@"张" andLastName:@"一" andSex:@"男" andAddress:@"山东省"]; Person* per2 = [per1 copy]; per2.lastName = @"二"; Person* per3 = [per1 copy]; per3.lastName = @"三"; Person* per4 = [per1 copy]; per4.lastName = @"四"; NSLog(@"内存地址:%@ 姓:%@ 名:%@ 性别:%@ 地址:%@",per1,per1.firstName,per1.lastName,per1.sex,per1.address); NSLog(@"内存地址:%@ 姓:%@ 名:%@ 性别:%@ 地址:%@",per2,per2.firstName,per2.lastName,per2.sex,per2.address); NSLog(@"内存地址:%@ 姓:%@ 名:%@ 性别:%@ 地址:%@",per3,per3.firstName,per3.lastName,per3.sex,per3.address); NSLog(@"内存地址:%@ 姓:%@ 名:%@ 性别:%@ 地址:%@",per4,per4.firstName,per4.lastName,per4.sex,per4.address); } return 0; }
输出结果如下:
2016-05-24 22:08:59.949 设计模式之五原型模式[980:44674]内存地址:<Person:
0x100103a80>姓:张名:一性别:男地址:山东省
2016-05-24 22:08:59.950 设计模式之五原型模式[980:44674]内存地址:<Person:
0x100105b90>姓:张名:二性别:男地址:山东省
2016-05-24 22:08:59.950 设计模式之五原型模式[980:44674]内存地址:<Person:
0x100105bc0>姓:张名:三性别:男地址:山东省
2016-05-24 22:08:59.950 设计模式之五原型模式[980:44674]内存地址:<Person:
0x100105bf0>姓:张名:四性别:男地址:山东省
Program ended with exit code: 0
可以看到,两次输出结果除内存地址(内存地址由运行时系统自动分配)外,完全相同。且使用原型模式后,只需要根据现有对象进行copy,创建出一个新的对象,将新对象中个别不同于原对象的属性更改即可。
以上为我个人对原型模式的简单理解,如有不到之处,敬请指正。
未完待续。。。
相关文章推荐
- 深入了解Qt(二)之元对象系统(Meta-Object System)
- Object-C 之 字符串
- object_constructor
- iOS:Objective-C中Self和Super详解
- VC++之 CreateEvent和SetEvent及WaitForSingleObject的用法
- List<Map<String,Object>> 的快速排序
- Struts2_Object-Graph Navigation Language(OGNL)
- Object类
- libz.so.1: cannot open shared object file: No such file or directory
- 一个类学习android基础动画类(ObjectAnimator和AnimatorSet和ValueAnimator)
- Python object new style class inheritance
- 深入了解Qt(一)之QObject
- %1$s和Object...以及getString() 和 getResources().getString()用法区别
- Javascript的Object探究
- We don't need no bounding-boxes: Training object class detectors using only human verificatio
- Online Object Tracking: A Benchmark 翻译
- csharp: DataRelation objects to represent a parent/child/Level relationship
- csharp: DataRelation objects to represent a parent/child/Level relationship
- Objective-C 预处理器(The Preprocessor) 宏
- csharp: DataRelation objects to represent a parent/child/Level relationship