原型模式概念:git
原型模式定義:github
原型模式UML圖以下:數組
客戶端引用着抽象父類Prototype類,父類Prototype類定義了clone的方法,Prototype類的子類實現clone方法; app
什麼時候考慮使用原型模式呢? 框架
Cocoa Touch框架中的應用 函數
NSObject根類性能
實際例子以下: atom
如今須要作個畫板功能,功能點兩個:1.實現畫線;2.實現畫點; 線的特性:顏色,寬度; 點的特徵:顏色,Size大小; 下面設計了三個類和一個協議來表示它們的邏輯關係。
@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類:最簡單,它只須要表示一個位置spa
@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]; }
第二版本:具有「複製」能力的加強型自定義對象(原型模式)
@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; } @end
@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性能有很好的做用。