迭代器模式(Iterator Pattern)
# 迭代器模式(Iterator Pattern)
迭代器模式(Iterator Pattern)是一种行为设计模式,它提供一种访问聚合对象(如列表、集合等)元素的统一接口,而无需了解聚合对象的内部结构。该模式将遍历与实现解耦,使得遍历算法可以独立于聚合对象变化而独立改变。
以下是对迭代器模式的描述:
# 概念
迭代器模式允许客户端以统一的方式遍历聚合对象中的元素,而不需要关注聚合对象的内部结构。它将遍历的责任委托给迭代器对象,该对象负责跟踪当前元素的位置并提供访问元素的方法。
# 思想
迭代器模式的核心思想是将遍历操作与聚合对象分离,通过迭代器对象对聚合对象进行遍历。这种解耦方式使得聚合对象可以独立于具体的迭代算法进行变化。
# 角色
- 客户端(Client):使用迭代器对象遍历聚合对象中的元素。
- 聚合对象(Aggregate):定义创建相应迭代器对象的接口。
- 迭代器对象(Iterator):提供访问聚合对象中元素的接口。
# 优点
- 简化了聚合对象的接口,客户端不需要了解聚合对象的内部结构。
- 支持多种遍历方式,客户端可以根据需要选择合适的迭代器。
- 将遍历算法与聚合对象解耦,使得聚合对象和遍历算法可以独立变化。
# 缺点
- 迭代器模式增加了代码的复杂性,需要额外定义迭代器对象和聚合对象的接口。
# 类图
@startuml
class Client
class Aggregate {
+createIterator(): Iterator
}
class Iterator {
+hasNext(): bool
+next(): Element
}
class ConcreteAggregate {
-elements: Element[]
}
class ConcreteIterator {
-aggregate: ConcreteAggregate
-current: int
}
interface Element
class ConcreteElementA
class ConcreteElementB
Client --> Aggregate
Client --> Iterator
Aggregate --> Iterator
Aggregate <|-- ConcreteAggregate
Iterator <|-- ConcreteIterator
ConcreteAggregate --> ConcreteIterator
Iterator ..> Element
ConcreteElementA --|> Element
ConcreteElementB --|> Element
@enduml
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
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
# 时序图
@startuml
hide footbox
participant Client
participant Aggregate
participant Iterator
participant ConcreteAggregate
participant ConcreteIterator
participant Element
Client -> Aggregate: createIterator()
activate Aggregate
Aggregate -> Iterator: createIterator()
activate Iterator
Iterator -> ConcreteIterator: new ConcreteIterator(aggregate)
activate ConcreteIterator
ConcreteIterator --> Iterator
Iterator --> Aggregate
deactivate Iterator
deactivate Aggregate
Client -> Iterator: hasNext()
activate Iterator
Iterator -> ConcreteIterator: hasNext()
activate ConcreteIterator
ConcreteIterator -> ConcreteAggregate: getElements()
activate ConcreteAggregate
ConcreteAggregate --> ConcreteIterator: elements
deactivate ConcreteAggregate
ConcreteIterator -> ConcreteIterator: current < elements.length
deactivate ConcreteIterator
ConcreteIterator --> Iterator: true
deactivate Iterator
Client -> Iterator: next()
activate Iterator
Iterator -> ConcreteIterator: next()
activate ConcreteIterator
ConcreteIterator -> ConcreteAggregate: getElements()
activate ConcreteAggregate
ConcreteAggregate --> ConcreteIterator: elements
deactivate ConcreteAggregate
ConcreteIterator -> ConcreteIterator: current++
deactivate ConcreteIterator
ConcreteIterator -> ConcreteIterator: current < elements.length
deactivate ConcreteIterator
ConcreteIterator --> Iterator: true
Iterator -> ConcreteIterator: getCurrent()
activate ConcreteIterator
ConcreteIterator --> Iterator: elements[current]
deactivate ConcreteIterator
deactivate Iterator
@enduml
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
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
# 示例代码
#include <iostream>
#include <vector>
// Element interface
class Element {
public:
virtual void print() const = 0;
};
// Concrete element A
class ConcreteElementA : public Element {
public:
void print() const override {
std::cout << "Concrete Element A" << std::endl;
}
};
// Concrete element B
class ConcreteElementB : public Element {
public:
void print() const override {
std::cout << "Concrete Element B" << std::endl;
}
};
// Iterator interface
class Iterator {
public:
virtual bool hasNext() const = 0;
virtual Element* next() = 0;
};
// Concrete iterator
class ConcreteIterator : public Iterator {
public:
ConcreteIterator(std::vector<Element*>& elements) : elements_(elements), current_(0) {}
bool hasNext() const override {
return current_ < elements_.size();
}
Element* next() override {
return elements_[current_++];
}
private:
std::vector<Element*>& elements_;
int current_;
};
// Aggregate interface
class Aggregate {
public:
virtual Iterator* createIterator() = 0;
};
// Concrete aggregate
class ConcreteAggregate : public Aggregate {
public:
Iterator* createIterator() override {
return new ConcreteIterator(elements_);
}
void addElement(Element* element) {
elements_.push_back(element);
}
private:
std::vector<Element*> elements_;
};
// Client
void clientCode(Aggregate* aggregate) {
Iterator* iterator = aggregate->createIterator();
while (iterator->hasNext()) {
Element* element = iterator->next();
element->print();
}
delete iterator;
}
int main() {
ConcreteAggregate aggregate;
aggregate.addElement(new ConcreteElementA());
aggregate.addElement(new ConcreteElementB());
clientCode(&aggregate);
return 0;
}
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
运行结果:
Concrete Element A
Concrete Element B
1
2
2
在示例代码中,我们首先定义了一个抽象的元素接口(Element
),并有两个具体的元素类(ConcreteElementA
和ConcreteElementB
)。接着定义了一个迭代器接口(Iterator
),并有一个具体的迭代器类(ConcreteIterator
)实现该接口。
然后定义了聚合对象接口(Aggregate
)及其具体实现类(ConcreteAggregate
)。聚合对象类中包含了一个动态数组来存储元素对象,并实现了创建相应迭代器对象的方法。
最后,在客户端代码中,我们创建了一个具体聚合对象(ConcreteAggregate
)并添加了两个具体元素对象(ConcreteElementA
和ConcreteElementB
)。然后调用clientCode
函数进行遍历,客户端无需关注聚合对象内部的元素存储方式,而是通过迭代器对象遍历聚合对象中的元素,并输出每个元素的内容。
编辑 (opens new window)
上次更新: 2023/06/09, 13:17:31
- 01
- Linux系统移植(五)--- 制作、烧录镜像并启动Linux02-05
- 03
- Linux系统移植(三)--- Linux kernel移植02-05