迭代器模式(Iterator),提供一種方法順序訪問一個聚合對象中的各類元素,而又不暴露該對象的內部表示。開發過程當中,咱們可能須要針對不一樣的需求,可能須要以不一樣的方式來遍歷整個整合對象,可是咱們不但願遍歷的對象內部存儲結構被外部知道,那麼能夠將對象包裝成一個迭代器,迭代器中定義中遍歷對象的方法下一個,是否存在下一個對象,刪除等遍歷須要的統一接口,迭代器在Java和.NET使用的比較多,自定義實現葉很是簡單,能夠簡單的看一下迭代器模式的UML類圖。數組
迭代器定義基本的遍歷操做方法,容器定義公共的建立迭代器的方法,子類負責實現具體須要引用的迭代器,咱們能夠假設圖書館是一個抽象容器,圖書館下面分爲國家圖書館和我的圖書館,我的圖書館存儲書籍的方式是可變數組存儲書籍,國家圖書館數據存儲書籍,分別建立不一樣的迭代器;測試
BookLibrary容器接口:atom
@protocol BoolLibraryProtocol<NSObject> @optional -(Iterator *)createIterator; @end @interface BookLibrary : NSObject<BoolLibraryProtocol> @end
CountryBookLibrary國家圖書館:spa
@interface CountryBookLibrary() @property (strong,nonatomic) NSArray *bookArr; @end @implementation CountryBookLibrary - (instancetype)init { self = [super init]; if (self) { Book *one=[self addBook:@"CountryBookLibrary" price:10]; Book *next=[self addBook:@"博客園-FlyElephant" price:20]; self.bookArr=@[one,next]; } return self; } -(Iterator *)createIterator{ return [[CountryIterator alloc]initWithData:self.bookArr]; } -(Book *)addBook:(NSString *)bookName price:(float)price{ Book *book=[[Book alloc]init]; book.bookName=bookName; book.price=price; return book; } @end
PersonLibraryBook我的圖書館:對象
@interface PersonBookLibray() @property (strong,nonatomic) NSMutableArray *books; @end @implementation PersonBookLibray - (instancetype)init { self = [super init]; if (self) { [self addBook:@"PersonIterator" price:100]; [self addBook:@"博客園-FlyElephant" price:200]; } return self; } -(Iterator *)createIterator{ return [[PersonIterator alloc]initWithData:self.books]; } -(void)addBook:(NSString *)bookName price:(float)price{ Book *book=[[Book alloc]init]; book.bookName=bookName; book.price=price; [self.books addObject:book]; } #pragma mark - getter and setter -(NSMutableArray *)books{ if (!_books) { _books=[[NSMutableArray alloc]init]; } return _books; } @end
迭代器Iterator:blog
@protocol IteratorProtocol <NSObject> @optional -(Boolean)hasNext; @optional -(id)next; @end @interface Iterator : NSObject<IteratorProtocol> @end
國家圖書館引用的迭代器:接口
@interface CountryIterator() @property (strong,nonatomic) NSArray *arr; @property (assign,nonatomic) NSInteger position; @end @implementation CountryIterator -(instancetype)initWithData:(NSArray *)data{ self=[super init]; if (self) { self.arr=data; } return self; } -(Boolean)hasNext{ if (self.position>=[self.arr count]||!self.arr[self.position]) { return false; }else{ return true; } } -(id)next{ Book *book=self.arr[self.position]; self.position+=1; return book; } @end
我的圖書館引用的迭代器:開發
@interface PersonIterator() @property (assign,nonatomic) NSInteger position; @property (strong,nonatomic) NSMutableArray *mutableArr; @end @implementation PersonIterator -(instancetype)initWithData:(NSMutableArray *)data{ self=[super init]; if (self) { self.mutableArr=data; } return self; } -(Boolean)hasNext{ if (self.position>=[self.mutableArr count]||![self.mutableArr objectAtIndex:self.position]) { return false; }else{ return true; } } -(id)next{ Book *book=[self.mutableArr objectAtIndex:self.position]; self.position+=1; return book; } @end
實際調用:get
-(void)iteratorDesign{ BookLibrary *personLibrary=[[PersonBookLibray alloc]init]; Iterator *personIterator=[personLibrary createIterator]; [self logLibraryInfo:personIterator]; BookLibrary *countryLibrary=[[CountryBookLibrary alloc]init]; Iterator *countryIterator=[countryLibrary createIterator]; [self logLibraryInfo:countryIterator]; } -(void)logLibraryInfo:(Iterator *)iterator{ while ([iterator hasNext]) { Book *book=[iterator next]; NSLog(@"書名:%@--價格:%ld",book.bookName,book.price); } }
測試結果:博客
迭代器模式的優勢:支持以不一樣的方式遍歷一個聚合對象(不一樣的聚合對象不一樣的遍歷方式),迭代器簡化了聚合類(統一接口),在迭代器模式中,增長新的聚合類和迭代器類都很方便,無須修改原有代碼(假設新增字典迭代器,直接添加就行,符合對擴展開放,對修改關閉的原則0)
缺點: 迭代器模式將存儲數據和遍歷數據的職責分離,增長新的聚合類須要對應增長新的迭代器類,類的個數成對增長,這在必定程度上增長了系統的複雜性。不過集合類型總共就幾種,基本上系統使用沒有問題,我的使用的需注意一下;