迭代器模式用于访问组合对象。迭代器知晓组合对象的内部结构,将迭代的实现细节屏蔽在迭代器内部,而组合对象本身不负责遍历。

迭代器模式允许外部遍历整个对象而不暴露组合对象的内部实现。

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
class SocialNetwork {
public:
virtual ProfileIterator* createFriendsIterator(int profileId) const = 0;
virtual ProfileIterator* createCoworkersIterator(int profileId) const = 0;
virtual ~SocialNetwork() {}
};

class Facebook: public SocialNetwork {
ProfileIterator* createFriendsIterator(int profileId) override {
return new FacebookIterator(this, profileId, "friends");
}
ProfileIterator* createCoworkersIterator(int profileId) override {
return new FacebookIterator(this, profileId, "coworkers");
}
};

class ProfileIterator{
public:
virtual Profile* getNext() = 0;
virtual bool hasMore() const = 0;
};

class FacebookIterator: public ProfileIterator {
private:
Facebook* facebook;
int profileId;
std::string type;
int currentPosition;
std::vector<Profile*> cache;

void lazyInit() {
if (cache.size() == 0)
cache = facebook->socialGraphRequest(profileId, type);
}

public:
FacebookIterator(Facebook* fb, int id, std::string t): facebook(fb), profileId(id), type(t), currentPosition(0) {}

Profile* getNext() override {
if (hasMore()) {
auto result = cache[currentPosition];
currentPosition++;
return result;
}
}

bool hasMore() const override {
lazyInit();
return currentPosition < cache.size();
}
};

class SocialSpammer {
public:
void send(ProfileIterator* iterator, std::string& message) {
while(iterator->hasMore()) {
auto profile = iterator->getNext();
System.sendEmail(profile->getEmail(), message);
}
}
};

int main() {
SocialSpammer spammer;
Facebook facebook;
FacebookIterator* iterator = facebook.createFriendsIterator(1);
spammer.send(iterator, "some spam");
delete iterator;
return 0;
}

此外,C++中还有一种泛型写法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
template <typename T, typename U> // T: 普通对象类型,U:组合对象类型
class Iterator {
public:
typedef typename std::vector<T>::iterator iter_type;
Iterator(U* p_data, bool reverse = false): m_p_data_(p_data) {
m_it_ = m_p_data_->m_data_.begin();
}
void First() {
m_it_ = m_p_data_->m_data_.begin();
}
void Next() {
m_it_++;
}
bool IsDone() {
return (m_it_ == m_p_data_->m_data_.end());
}

iter_type Current() {
return m_it_;
}
private:
U* m_p_data_;
iter_type m_it_;
}