今天和大家分享的是迭代器模式。接触过C#或者Java的同学应该对迭代器都有所了解,想必大家对迭代器的概念已经不陌生了,下面还是给出定义和类图关系,大家体会一下就明白了。
迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。
那么一般在什么时候才会用迭代器模式呢?当你需要访问一个聚集对象,而且不管这些对象是什么都需要遍历的时候,你就应该考虑用迭代器模式。另外,当你需要对聚集有多种方式遍历时,也可以考虑用迭代器模式。
说了这么多,下面给大家展示一下类关系图。
上图中Client的右边是迭代器,左边是具体迭代的类型,在迭代器内部对具体需要迭代的类型进行了引用,还算不难理解吧,呵呵。其实,看起来是为了对具体类型进行解耦。好啦,下面给出具体的代码实现,简单的模拟了迭代器模式。
-
Iterator类接口
1
2
3
4
5
6
7
8
|
#import <Foundation/Foundation.h>
@interface
Iterator:
NSObject
-(
id
)First;
-(
id
)Next;
-(
BOOL
)IsDone;
-(
id
)CurrentItem;
@end
|
-
Iterator类实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
#import "Iterator.h"
@implementation
Iterator
-(
id
)First{
return
nil
;
}
-(
id
)Next{
return
nil
;
}
-(
BOOL
)IsDone{
return
NO
;
}
-(
id
)CurrentItem{
return
nil
;
}
@end
|
-
ConcreteIterator类接口
1
2
3
4
5
6
7
8
9
|
#import "Iterator.h"
@class
ConcreteAggregate;
@interface
ConcreteIterator :Iterator{
ConcreteAggregate *myAggregate;
int
current;
}
-(ConcreteIterator*)MyInit:(ConcreteAggregate*)aggregate;
@end
|
-
ConcreteIterator类实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
#import "ConcreteIterator.h"
#import "ConcreteAggregate.h"
@implementation
ConcreteIterator
-(ConcreteIterator*)MyInit:(ConcreteAggregate*)aggregate{
myAggregate = aggregate;
return
self
;
}
-(
id
)First{
return
[myAggregate GetObject:0];
}
-(
id
)Next{
current++;
if
(current< [myAggregate GetCount])
return
[myAggregate GetObject:current];
else
{
return
nil
;
}
}
-(
BOOL
)IsDone{
return
current>= [myAggregate GetCount] ?
YES
:
NO
;
}
-(
id
)CurrentItem{
return
[myAggregate GetObject:current];
}
@end
|
-
Aggregate类接口
1
2
3
4
5
6
|
#import <Foundation/Foundation.h>
@class
Iterator;
@interface
Aggregate:
NSObject
-(Iterator*)CreateIterator;
@end
|
-
Aggregate类实现
1
2
3
4
5
6
7
8
|
#import "Aggregate.h"
#import "Iterator.h"
@implementation
Aggregate
-(Iterator*)CreateIterator{
return
[[Iterator alloc]init];
}
@end
|
-
ConcreteAggregate类接口
1
2
3
4
5
6
7
8
9
|
#import "Aggregate.h"
@interface
ConcreteAggregate:Aggregate{
NSMutableArray
*items;
}
-(
int
)GetCount;
-(
id
)GetObject:(
int
)index;
-(
void
)InsertObject:(
id
)Obj;
@end
|
-
ConcreteAggregate类实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
#import "ConcreteAggregate.h"
#import "Iterator.h"
@implementation
ConcreteAggregate
-(
id
)init{
if
(
self
== [
super
init]){
items = [
NSMutableArray
new
];
}
return
self
;
}
-(Iterator*)CreateIterator{
return
[[Iterator alloc]init];
}
-(
id
)GetObject:(
int
)index{
return
[items objectAtIndex:index];
}
-(
void
)InsertObject:(
id
)Obj{
[items addObject:Obj];
}
-(
int
)GetCount{
return
[items count];
}
@end
|
-
Main方法调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
#import <Foundation/Foundation.h>
#import "ConcreteAggregate.h"
#import "Iterator.h"
#import "ConcreteIterator.h"
int
main (
int
argc,
const
char
*argv[])
{
@autoreleasepool
{
ConcreteAggregate *a = [[ConcreteAggregate alloc]init];
[a InsertObject:@
"张三"
];
[a InsertObject:@
"李四"
];
[a InsertObject:@
"王二"
];
[a InsertObject:@
"麻子"
];
NSLog
(@
"Count:%d"
, [a GetCount]);
Iterator *i = [[ConcreteIterator alloc]MyInit:a];
while
(![i IsDone]) {
NSLog
(@
"%@,请买票"
,[i CurrentItem]);
[i Next];
}
}
return
0;
}
|
好啦,上面的四个类型简单实现了迭代器模式,其实迭代器模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可以让外部代码透明地访问集合内部地数据。