設計模式應用場景之Model設計中能夠用到的設計模式

在開發中,不一樣的場景適用不一樣的設計模式。對於開發建模方面,能夠根據模型的抽象類型設計成簡單屬性模式和複雜組合模式。
由於組合模式中的屬性爲多種類型對象,可操做性也比較靈活。
而針對這種複雜數據結構,有兩種設計模式可使用:
1.組合模式
2.迭代器模式
 
組合模式篇
組合模式簡介:
1.組合模式就是一個樹形數據結構
2.對組合對象的查詢,訪問都是遞歸操做。
3.全部的節點都會實現同一套接口或者繼承自 同一個抽象父類。
4.每一個對象都是其中的一個節點,不管葉子節點和組件節點都有相同的接口。只是葉子節點的接口返回爲空,組件節點的接口實現接口。
5.組合模式讓咱們把相同基類型的對象組合到樹狀結構中,其中父節點包含同類型的子節點
 
組合模式的對象圖以下:
aComposite:組件節點,下面包含子節點
aLeaf:葉子節點,下面沒有子節點。
 
組合模式的類圖以下:
aComposite:組件節點中包含的動做以下:
1.基本操做
2.對子節點的各類操做(增,刪,查)
 
aLeaf:葉子節點總包含的動做以下:
1.基本操做
由於葉子節點是最底層,最簡單的節點,因此它所包含的動做也是最簡單的,只有做用節點最基本的operation功能。
 
組合模式的做用:
1.將對象組合成樹形結構,以表示「總體-部分」的層次結構
2.組合模式使得客戶端對單個對象和組合對象的操做具備一致性。使客戶端對組件節點和葉子節點進行處理時,可以對它們的區別無感知,好像它們都是一樣的簡單對象。
 
組合模式的實際使用例子:
線段軌跡這個抽象事物爲例子,這個抽象例子中包含三種模型:
1.線段,它是一個組合模式模型,裏面能夠包含子線段,鏈接點,點。
2.鏈接點,它是線段(或子線段)中的內容鏈接部分。
3.點,只有一個點的線段或者長度爲0的線段。
 
這三種抽象事物的類UML圖以下:
 
這三種抽象事物的對象UML圖以下:
 

代碼實現以下:git

 1.先定義這三個類所共同遵照的協議:Mark協議
@protocol Mark <NSObject,NSCopying>
@property (nonatomic, strong) UIColor *color;
@property (nonatomic, assign) CGSize size;
@property (nonatomic, assign) CGPoint location;
- (void)addMark:(id<Mark>)mark;
- (void)removeMark:(id<Mark>)mark;
- (void)removeAllMarks;
- (id<Mark>)childAtIndex:(int)index;
- (id<Mark>)lastChild;
- (NSUInteger)count;
@end

2.Stroke類實現Mark協議以下:github

@interface Stroke() @property (nonatomic, strong) NSMutableArray<id<Mark>> *markArray; @end

@implementation Stroke @synthesize color,location,size; #pragma mark - 屬性操做
- (void)setLocation:(CGPoint)location {} - (CGPoint)location { if (_markArray.count) { return [[_markArray firstObject] location]; } else { return CGPointZero; } } #pragma mark - Mark操做
- (NSMutableArray<id<Mark>> *)markArray { if (!_markArray) { _markArray = @[].mutableCopy; } return _markArray; } - (void)addMark:(id<Mark>)mark { [self.markArray addObject:mark]; } - (void)removeMark:(id<Mark>)mark { //在當前節點中,就從當前節點刪除,不在當前節點,就深度查找子節點
    if ([_markArray containsObject:mark]) { [self.markArray removeObject:mark]; } else { [_markArray makeObjectsPerformSelector:@selector(removeMark:) withObject:mark]; } } - (void)removeAllMarks { [self.markArray removeAllObjects]; } - (id<Mark>)childAtIndex:(int)index { if (self.markArray.count == 0) { return nil; } else { return self.markArray[index]; } } - (id<Mark>)lastChild { return self.markArray.lastObject; } - (NSUInteger)count { return self.markArray.count; }
3.Vertex實現Mark協議以下:
 
@implementation Vertex @synthesize location; @dynamic color,size; - (instancetype)initWithLocation:(CGPoint)location { self = [super init]; if (self) { self.location = location; } return self; } #pragma mark - 屬性操做
- (UIColor *)color{return nil;} - (void)setColor:(UIColor *)color{} - (CGSize)size{return CGSizeZero;} - (void)setSize:(CGSize)size{} #pragma mark - Mark操做
- (void)addMark:(id<Mark>)mark {} - (void)removeMark:(id<Mark>)mark {} - (void)removeAllMarks {} - (id<Mark>)childAtIndex:(int)index {return nil;} - (id<Mark>)lastChild {return nil;} - (NSUInteger)count {return 0;}

4.Dot類實現Mark協議以下:設計模式

@interface Dot : Vertex @end

@implementation Dot @synthesize color,size;

由於Dot類基礎自Vertex,因此對象Mark對象的操做使用父類的就行了數據結構

 

迭代器模式篇函數

迭代器模式簡介:atom

1.迭代器提供了一種 順序訪問聚合對象(集合)中元素的方法,而無需暴露聚合對象(集合)的底層表示和結構細節。
2. 爲聚合對象(集合)配置迭代器後,遍歷集合元素的任務從集合 轉移給了迭代器對象。
3.請問啥叫迭代器模式?
答:針對抽象集合的迭代行爲 而採用的設計模式,叫作迭代器模式
 
迭代器模式的對象圖以下:
 

簡單表示,迭代器持有着聚合對象spa

 
標準表示:
1.抽象聚合體Aggregate中定義了建立迭代器的接口,實例聚合類ConcreteAggregate實現建立迭代器的接口,返回本身類型的迭代器。
2.抽象迭代器Iterator定義了通用迭代方法,實例迭代器ConcreteIterator實現迭代方法接口。
 
迭代器模式的種類:
1.外部迭代器
由聚合對象直接將本身的迭代器返回給調用者,調用者進行靈活使用,舉例以下:
NSEnumerator *enumerator = [self enumerator]; id <Mark> mark; while (mark = [enumerator nextObject]) { [mark lastChild] }
2.內部迭代器
由聚合體提供一個迭代接口,這個迭代接口中有一個參數,該參數須要傳遞一個供聚合體內部在遍歷時調用的「代碼塊」。這樣在
聚合體內部遍歷時,就將每一個對象執行傳遞過來的預先定義好的函數。
舉例以下:
 
self.stroke = [Stroke new]; [self.stroke enumerateMarksUsingBlock:^(id<Mark> mark, BOOL *stop) { }]

 

迭代器模式的實際使用例子:設計

如今繼續使用剛纔使用舉的抽象事物「線段軌跡」
這個抽象例子中包含三種模型:線段,鏈接點,點。
 
 在Mark協議中定義迭代器接口,返回外部迭代器
 

代碼實現以下:3d

Mark協議接口定義code

@protocol Mark <NSObject,NSCopying> @property (nonatomic, strong) UIColor *color; @property (nonatomic, assign) CGSize size; @property (nonatomic, assign) CGPoint location; - (void)addMark:(id<Mark>)mark; - (void)removeMark:(id<Mark>)mark; - (void)removeAllMarks; - (id<Mark>)childAtIndex:(int)index; - (id<Mark>)lastChild; - (NSUInteger)count; - (instancetype)copy; //迭代器
- (NSEnumerator *)enumerator; @end;

Stroke類接口實現

@interface Stroke() @property (nonatomic, strong) NSMutableArray<id<Mark>> *markArray; @end

@implementation Stroke @synthesize color,location,size; #pragma mark - 屬性操做
- (void)setLocation:(CGPoint)location {} - (CGPoint)location { if (_markArray.count) { return [[_markArray firstObject] location]; } else { return CGPointZero; } } #pragma mark - Mark操做
- (NSMutableArray<id<Mark>> *)markArray { if (!_markArray) { _markArray = @[].mutableCopy; } return _markArray; } - (void)addMark:(id<Mark>)mark { [self.markArray addObject:mark]; } - (void)removeMark:(id<Mark>)mark { //在當前節點中,就從當前節點刪除,不在當前節點,就深度查找子節點
    if ([_markArray containsObject:mark]) { [self.markArray removeObject:mark]; } else { [_markArray makeObjectsPerformSelector:@selector(removeMark:) withObject:mark]; } } - (void)removeAllMarks { [self.markArray removeAllObjects]; } - (id<Mark>)childAtIndex:(int)index { if (self.markArray.count == 0) { return nil; } else { return self.markArray[index]; } } - (id<Mark>)lastChild { return self.markArray.lastObject; } - (NSUInteger)count { return self.markArray.count; } #pragma mark - 迭代器
- (NSEnumerator *)enumerator { return [[ZHFMarkEnumerator alloc] initWithMark:self]; }

 

 在Mark協議中定義內部迭代器接口:
 
 

代碼實現以下:

Mark協議接口定義
@protocol Mark <NSObject,NSCopying> @property (nonatomic, strong) UIColor *color; @property (nonatomic, assign) CGSize size; @property (nonatomic, assign) CGPoint location; - (void)addMark:(id<Mark>)mark; - (void)removeMark:(id<Mark>)mark; - (void)removeAllMarks; - (id<Mark>)childAtIndex:(int)index; - (id<Mark>)lastChild; - (NSUInteger)count; - (instancetype)copy; //迭代器
- (NSEnumerator *)enumerator; //內部迭代器
- (void)enumerateMarksUsingBlock:(void (^) (id <Mark> mark, BOOL *stop))block; @end;
Stroke類接口實現
 
@interface Stroke() @property (nonatomic, strong) NSMutableArray<id<Mark>> *markArray; @end

@implementation Stroke @synthesize color,location,size; #pragma mark - 屬性操做
- (void)setLocation:(CGPoint)location {} - (CGPoint)location { if (_markArray.count) { return [[_markArray firstObject] location]; } else { return CGPointZero; } } #pragma mark - Mark操做
- (NSMutableArray<id<Mark>> *)markArray { if (!_markArray) { _markArray = @[].mutableCopy; } return _markArray; } - (void)addMark:(id<Mark>)mark { [self.markArray addObject:mark]; } - (void)removeMark:(id<Mark>)mark { //在當前節點中,就從當前節點刪除,不在當前節點,就深度查找子節點
    if ([_markArray containsObject:mark]) { [self.markArray removeObject:mark]; } else { [_markArray makeObjectsPerformSelector:@selector(removeMark:) withObject:mark]; } } - (void)removeAllMarks { [self.markArray removeAllObjects]; } - (id<Mark>)childAtIndex:(int)index { if (self.markArray.count == 0) { return nil; } else { return self.markArray[index]; } } - (id<Mark>)lastChild { return self.markArray.lastObject; } - (NSUInteger)count { return self.markArray.count; } #pragma mark - 迭代器
- (NSEnumerator *)enumerator { return [[ZHFMarkEnumerator alloc] initWithMark:self]; } - (void)enumerateMarksUsingBlock:(void (^)(id<Mark>, BOOL *stop))block { NSEnumerator *enumerator = [self enumerator]; id <Mark> mark; BOOL *stop = NO; for (id <Mark> mark in enumerator) { block(mark, &stop); if (stop) { break; } } }
熟練使用設計模式是編寫高擴展,高穩定,高複用,三高代碼很重要的一項技能。願你我一同砥礪前行。
完整的項目代碼地址以下:
目前項目尚未徹底結束,處於持續完善中...
相關文章
相關標籤/搜索