标签:21 第一篇 self mark color location 设计模式 id size
原型模式概念:
- 把某些对象变成”塑胶印章",让其拥有“复制”自身并得到其复制品的能力。
- “复制”指:用同一个模具,生产一系列的产品。这些产品只是某些颜色,特征不同而已,只需进行简单修改。
- 原型模式“复制”的对象都是真实的副本实例;
原型模式定义:
- 应用“复制”操作的模式,称为原型模式。
原型模式UML图如下:
客户端引用着抽象父类Prototype类,父类Prototype类定义了clone的方法,Prototype类的子类实现clone方法;
何时考虑使用原型模式呢?
- 不想要产品工厂
- 不同实例间的差异仅仅是属性状态的不同,因此复制比手工创建更加便捷。
- 手工创建不容易。像复杂的组合对象,创建起来没有复制来的快。
Cocoa Touch框架中的应用
NSCopying协议 Cocoa Touch为NSObject的派生类提供了实现深复制的协议NSCopying; NSObject的子类需要实现协议NSCopying的方法copyingWithZone:
NSObject根类
NSObject提供的实例方法copy底层调用也是copyingWithZone: 所以遵守了NSCopying协议的对象,需要实现方法copyingWithZone,不然会引起异常。
实际例子如下:
现在需要做个画板功能,功能点两个:1.实现画线;2.实现画点; 线的特性:颜色,宽度; 点的特征:颜色,Size大小; 下面设计了三个类和一个协议来表示它们的逻辑关系。第一个版本设计:不具备“复制”能力的简单自定义对象 基本关系类型的UML图 代码实现如下: Mark协议:
@protocol Mark <NSObject> @property (nonatomic, assign) CGSize size; @property (nonatomic, strong) UIColor *color; @property (nonatomic, assign) CGPoint location; - (void)addMark:(id<Mark>)mark; - (void)removeMark:(id<Mark>)mark; @end
Vertex类:最简单,它只需要表示一个位置
@implementation Vertex @synthesize location = _location; @dynamic color,size; @end
Dot类:继承自Vertex, 由于其表示一个独立的点,所以有size,color属性值
@implementation Dot @synthesize color = _color, size = _size; @end
Stroke类:是有若干个Vertex连接而成的线段。
@implementation Stroke @dynamic location; @synthesize color = _color, size = _size; #pragma mark - Life Cycle #pragma mark - Getter, Setter - (CGPoint)location { return [self.marksArray.firstObject location]; }
第二版本:具备“复制”能力的增强型自定义对象(原型模式)
代码实现如下: Mark协议:@protocol Mark <NSObject> @property (nonatomic, assign) CGSize size; @property (nonatomic, strong) UIColor *color; @property (nonatomic, assign) CGPoint location; - (void)addMark:(id<Mark>)mark; - (void)removeMark:(id<Mark>)mark; - (id<Mark>)copy; @end
Vertex类:新增了一个通过自身location创建的构造函数,为子类创建做准备
@implementation Vertex @synthesize location = _location; @dynamic color,size; - (instancetype)initWithLocation:(CGPoint)location { self = [super init]; if (self) { _location = location; } return self; } - (id)copyWithZone:(NSZone *)zone { Vertex *ver = [[[self class] alloc] initWithLocation:self.location]; return ver; } @end
Dot类:先通过父类的构造函数创建新对象,再对新对象设置属性
@implementation Dot @synthesize color = _color, size = _size; - (id)copyWithZone:(NSZone *)zone { Dot *dot = [[[self class] alloc] initWithLocation:self.location]; dot.size = self.size; dot.color = [UIColor colorWithCGColor:[self.color CGColor]]; return dot; } @endStroke类:先创建一个新对象,同时遍历旧对象的marksArray数组,对里面的所有对象(id<Mark>) 逐个进行copy
@implementation Stroke @dynamic location; @synthesize color = _color, size = _size; #pragma mark - Life Cycle #pragma mark - Getter, Setter - (CGPoint)location { return [self.marksArray.firstObject location]; } #pragma mark - Private Method - (id)copyWithZone:(NSZone *)zone { Stroke *stroke = [[[self class] alloc] init]; stroke.color = [UIColor colorWithCGColor:[self.color CGColor]]; stroke.size = self.size; NSMutableArray *arrayM = [NSMutableArray arrayWithCapacity:[self.marksArray count]]; for (id<Mark> mark in self.marksArray) { [arrayM addObject:[mark copy]]; } stroke.marksArray = arrayM; return stroke; } @end
对例子的实际使用 在触摸回调方法中记录触摸点信息
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event - (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
在全局变量中记录触摸点信息并设置属性监控,当有触摸点改变就触发监控函数,在监控函数中进行图像绘制
[self.scribble addObserver:self forKeyPath:@"mark" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
项目效果图如下:
原型模式在平时开发的复杂模型中使用频率较大,合理使用对于提高app性能有很好的作用。
DEMO地址:https://github.com/zhfei/Objective-C_Design_Patterns 具体在(Objective-C_Design_Patterns)WorkSpace下的(Design_Patterns_Demoes)Project项目下。
标签:21,第一篇,self,mark,color,location,设计模式,id,size 来源: https://www.cnblogs.com/zhou--fei/p/10659556.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。