长生栈 长生栈
首页
  • 编程语言

    • C语言
    • C++
    • Java
    • Python
  • 数据结构和算法

    • 全排列算法实现
    • 动态规划算法
  • CMake
  • gitlab 安装和配置
  • docker快速搭建wordpress
  • electron+react开发和部署
  • Electron-创建你的应用程序
  • ImgUI编译环境
  • 搭建图集网站
  • 使用PlantUml画时序图
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Living Team

编程技术分享
首页
  • 编程语言

    • C语言
    • C++
    • Java
    • Python
  • 数据结构和算法

    • 全排列算法实现
    • 动态规划算法
  • CMake
  • gitlab 安装和配置
  • docker快速搭建wordpress
  • electron+react开发和部署
  • Electron-创建你的应用程序
  • ImgUI编译环境
  • 搭建图集网站
  • 使用PlantUml画时序图
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 创建型模式

  • 结构型模式

  • 行为型模式

    • 责任链模式(Chain of Responsibility Pattern)
    • 命令模式(Command Pattern)
    • 解释器模式(Interpreter Pattern)
    • 迭代器模式(Iterator Pattern)
      • 概念
      • 思想
      • 角色
      • 优点
      • 缺点
      • 类图
      • 时序图
      • 示例代码
    • 中介者模式(Mediator Pattern)
    • 备忘录模式(Memento Pattern)
    • 观察者模式(Observer Pattern)
    • 状态模式(State Pattern)
    • 策略模式(Strategy Pattern)
    • 模板方法模式(Template Method Pattern)
    • 访问者模式(Visitor Pattern)
  • 设计模式
  • 行为型模式
DC Wang
2023-05-28
目录

迭代器模式(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

# 时序图

@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

# 示例代码

#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

运行结果:

Concrete Element A
Concrete Element B
1
2

在示例代码中,我们首先定义了一个抽象的元素接口(Element),并有两个具体的元素类(ConcreteElementA和ConcreteElementB)。接着定义了一个迭代器接口(Iterator),并有一个具体的迭代器类(ConcreteIterator)实现该接口。

然后定义了聚合对象接口(Aggregate)及其具体实现类(ConcreteAggregate)。聚合对象类中包含了一个动态数组来存储元素对象,并实现了创建相应迭代器对象的方法。

最后,在客户端代码中,我们创建了一个具体聚合对象(ConcreteAggregate)并添加了两个具体元素对象(ConcreteElementA和ConcreteElementB)。然后调用clientCode函数进行遍历,客户端无需关注聚合对象内部的元素存储方式,而是通过迭代器对象遍历聚合对象中的元素,并输出每个元素的内容。

编辑 (opens new window)
#设计模式#行为型模式
上次更新: 2023/06/09, 13:17:31
解释器模式(Interpreter Pattern)
中介者模式(Mediator Pattern)

← 解释器模式(Interpreter Pattern) 中介者模式(Mediator Pattern)→

最近更新
01
ESP32-网络摄像头方案
06-14
02
ESP32-PWM驱动SG90舵机
06-14
03
ESP32-实时操作系统freertos
06-14
更多文章>
Theme by Vdoing | Copyright © 2019-2025 DC Wang All right reserved | 辽公网安备 21021102001125号 | 吉ICP备20001966号-2
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式