迭代器模式
迭代器模式的英文是Iterator Design Pattern,也叫作游标模式(Cursor Design Pattern)。它是用来遍历集合对象的。迭代器模式将集合对象的遍历操作从集合类中拆分出来,放到迭代器类中,让两者的职责更加单一。
先熟悉下iOS中实现的遍历容器的迭代器类。示例如下:
@interface DMFunctionModel : NSObject
@property (nonatomic, strong) NSString *functionId;
@property (nonatomic, strong) NSString *functionName;
@end
@implementation DMFunctionModel
@end
@interface DMDemo : NSObject
@property (nonatomic, strong) NSMutableArray *dataArray;
@end
@implementation DMDemo
- (void)test
{
NSEnumerator<DMFunctionModel *> *enumerator = [self.dataArray objectEnumerator];
DMFunctionModel *tmpFunctionModel = nil;
while (tmpFunctionModel = [enumerator nextObject]) {
NSLog(@"functionId:%@,functionName:%@", tmpFunctionModel.functionId, tmpFunctionModel.functionName);
}
}
- (NSMutableArray *)dataArray
{
if (_dataArray == nil) {
_dataArray = [[NSMutableArray alloc] init];
{
DMFunctionModel *functionModel = [[DMFunctionModel alloc] init];
functionModel.functionId = @"0101";
functionModel.functionName = @"创建型";
[_dataArray addObject:functionModel];
}
{
DMFunctionModel *functionModel = [[DMFunctionModel alloc] init];
functionModel.functionId = @"0102";
functionModel.functionName = @"结构型";
[_dataArray addObject:functionModel];
}
{
DMFunctionModel *functionModel = [[DMFunctionModel alloc] init];
functionModel.functionId = @"0103";
functionModel.functionName = @"行为型";
[_dataArray addObject:functionModel];
}
}
return _dataArray;
}
@end
现在定义一个新的数据结构DMMutableArray 线性容器,设计实现对应的迭代器。
@interface DMMutableArray<ObjectType> : NSObject
@property (nonatomic, assign, readonly) NSUInteger count;
- (void)addObject:(ObjectType)anObject;
- (instancetype)init;
- (ObjectType)objectAtIndex:(NSUInteger)index;
- (void)insertObject:(ObjectType)anObject atIndex:(NSUInteger)index;
- (void)removeLastObject;
- (void)removeObjectAtIndex:(NSUInteger)index;
- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(ObjectType)anObject;
@end
@interface DMMutableArray ()
@property (nonatomic, strong) NSMutableArray *mArray;
@end
@implementation DMMutableArray
- (instancetype)init
{
if (self = [super init]) {
}
return self;
}
- (id)objectAtIndex:(NSUInteger)index
{
return [self.mArray objectAtIndex:index];
}
- (void)addObject:(id)anObject
{
[self.mArray addObject:anObject];
}
- (NSUInteger)count
{
return [self.mArray count];
}
- (void)insertObject:(id)anObject atIndex:(NSUInteger)index
{
[self.mArray insertObject:anObject atIndex:index];
}
- (void)removeLastObject
{
[self.mArray removeLastObject];
}
- (void)removeObjectAtIndex:(NSUInteger)index
{
[self.mArray removeObjectAtIndex:index];
}
- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject
{
[self.mArray replaceObjectAtIndex:index withObject:anObject];
}
- (NSMutableArray *)mArray
{
if (_mArray == nil) {
_mArray = [[NSMutableArray alloc] init];
}
return _mArray;
}
@end
@interface DMMutableArrayIterator<ObjectType> : NSObject
- (instancetype)initWithDMMutableArray:(DMMutableArray<ObjectType> *)array;
- (BOOL)hasNext;
- (void)next;
- (ObjectType)currentItem;
@end
@interface DMMutableArrayIterator ()
@property (nonatomic, assign) NSInteger mCursor;
@property (nonatomic, strong) DMMutableArray *mArray;
@end
@implementation DMMutableArrayIterator
- (instancetype)initWithDMMutableArray:(DMMutableArray *)array
{
if (self = [super init]) {
self.mCursor = 0;
self.mArray = array;
}
return self;
}
- (BOOL)hasNext
{
BOOL bFlag = YES;
if (self.mCursor >= [self.mArray count]) {
bFlag = NO;
}
return bFlag;
}
- (void)next
{
self.mCursor += 1;
}
- (id)currentItem
{
return [self.mArray objectAtIndex:self.mCursor];
}
@end
@interface DMDemo : NSObject
@end
@implementation DMDemo
- (void)test
{
DMMutableArray *tmpArray = [[DMMutableArray alloc] init];
[tmpArray addObject:@"123"];
[tmpArray addObject:@"456"];
[tmpArray addObject:@"789"];
DMMutableArrayIterator *iterator = [[DMMutableArrayIterator alloc] initWithDMMutableArray:tmpArray];
while ([iterator hasNext]) {
NSString *curStr = [iterator currentItem];
NSLog(@"%@", curStr);
[iterator next];
}
}
@end
在上面的代码实现中,需要将待遍历的容器对象,通过初始化函数传递给迭代器。实际上,为了封装迭代器的创建细节,可以在容器中定义一个- (DMMutableArrayIterator *)iterator 方法,来创建对应的迭代器。
@class DMMutableArrayIterator;
@interface DMMutableArray<ObjectType> : NSObject
@property (assign, readonly) NSUInteger count;
- (void)addObject:(ObjectType)anObject;
- (instancetype)init;
- (ObjectType)objectAtIndex:(NSUInteger)index;
- (void)insertObject:(ObjectType)anObject atIndex:(NSUInteger)index;
- (void)removeLastObject;
- (void)removeObjectAtIndex:(NSUInteger)index;
- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(ObjectType)anObject;
- (DMMutableArrayIterator *)iterator;
@end
@interface DMMutableArray ()
@property (nonatomic, strong) NSMutableArray *mArray;
@end
@implementation DMMutableArray
- (instancetype)init
{
if (self = [super init]) {
}
return self;
}
- (id)objectAtIndex:(NSUInteger)index
{
return [self.mArray objectAtIndex:index];
}
- (void)addObject:(id)anObject
{
[self.mArray addObject:anObject];
}
- (NSUInteger)count
{
return [self.mArray count];
}
- (void)insertObject:(id)anObject atIndex:(NSUInteger)index
{
[self.mArray insertObject:anObject atIndex:index];
}
- (void)removeLastObject
{
[self.mArray removeLastObject];
}
- (void)removeObjectAtIndex:(NSUInteger)index
{
[self.mArray removeObjectAtIndex:index];
}
- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject
{
[self.mArray replaceObjectAtIndex:index withObject:anObject];
}
- (NSMutableArray *)mArray
{
if (_mArray == nil) {
_mArray = [[NSMutableArray alloc] init];
}
return _mArray;
}
- (DMMutableArrayIterator *)iterator
{
return [[DMMutableArrayIterator alloc] initWithDMMutableArray:self];
}
@end
使用示例如下
@interface DMDemo : NSObject
@end
@implementation DMDemo
- (void)test
DMMutableArrayIterator *iteratorTwo = [tmpArray iterator];
while ([iteratorTwo hasNext]) {
NSString *curStr = [iteratorTwo currentItem];
NSLog(@"%@", curStr);
[iteratorTwo next];
}
}
@end
总结一下迭代器的设计思路:
- 迭代器中需要定义 - (BOOL)hasNext 、- (void)next 、- (ObjectType)currentItem 三个最基本的方法
- 待遍历的容器对象通过依赖注入传递到迭代器类中
- 容器通过 - (DMMutableArrayIterator *)iterator 方法来创建迭代器。














网友评论