Skip to content

Commit

Permalink
update: refactory iterator
Browse files Browse the repository at this point in the history
  • Loading branch information
hscspring committed Oct 23, 2022
1 parent c4d9ba7 commit cf23e60
Showing 1 changed file with 147 additions and 26 deletions.
173 changes: 147 additions & 26 deletions docs/content/design_pattern/iterator.md
Original file line number Diff line number Diff line change
@@ -1,58 +1,179 @@
# 迭代器模式

## 设计动机
## 模式引入

**问题引入**
### 问题描述

实际生活中,我们经常遇到需要遍历一系列聚合对象的情况,比如排队买票,音乐播放列表等。当我们遍历这些对象时,由于它们本来是一个对象,导致我们不得不直接访问其内部列表。而且,如果我们要遍历另一个的对象时,同样的遍历方法又得重写一遍。
实际生活中,我们经常遇到需要遍历一系列聚集对象的情况,比如排队买票,音乐播放列表等。当我们遍历这些对象时,由于它们本来是一个对象,导致我们不得不直接访问其内部列表。而且,如果我们要遍历另一个的对象时,同样的遍历方法又得重写一遍。

**模式引入**
### 模式定义

像这种想要别人访问它的元素,但又不想暴露内部结构的情况,就可以使用迭代器模式,将对列表的访问和遍历放到一个迭代器对象,迭代器定义了访问元素的接口。此时,同样的遍历逻辑只需要实现一次。事实上,由于迭代器模式使用太普遍,大部分高级语言都已经对它进行了封装
像这种想要别人访问它的元素,但又不想暴露内部结构的情况,就可以使用迭代器模式。

## 模式介绍
迭代器模式(Iterator)是提供一种方法顺序访问一个聚集对象中各个元素,而又不暴露该对象的内部表示。

**模式定义**
### 问题分析

迭代器模式(Iterator)是提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示
将对列表的访问和遍历放到一个迭代器对象,迭代器定义访问元素的接口。此时,同样的遍历逻辑只需要实现一次。事实上,由于迭代器模式使用太普遍,大部分高级语言都已经对它进行了封装

**模式结构**
## 模式实现

![](img/iterator/iterator.jpg)
### 解决方案

迭代器模式主要包括聚集抽象类(Aggregate)、迭代抽象类(Iterator)、具体聚集类(ConcreteAggregate)、具体迭代器类(ConcreteIterator)。
- 首先定义抽象聚集对象:`Aggregate` 类,定义 `createIterator` 方法,用于创建一个迭代器。
- 然后定义一个具体聚集对象:`ConcreteAggretate` 类,除了重写抽象方法外,还需定义简单的 `get``set``count` 等方法。
- 定义抽象迭代器对象:`Iterator` 类,一般包括:`first``next``isDone``currentItem` 几个抽象方法。
- 定义具体迭代器对象:`ConreteIterator` 类,重写抽象方法,实现对对象的迭代。

- 迭代抽象类(Iterator):用于定义各种行为的抽象方法,统一接口。
- 具体迭代器类(ConcreteIterator):继承 Iterator,实现具体行为的方法。
### 代码实现

`Aggregate` 类:

```java
public abstract class Aggregate {
public abstract Iterator createIterator();
}
```

`ConcreteAggregate` 类:

```java
public class ConcreteAggregate extends Aggregate {
private List<Object> items = new ArrayList<>();

@Override
public Iterator createIterator() {
return new ConcreteIterator(this);
}

public int Count() {
return items.size();
}

public Object get(int index) {
return items.get(index);
}

public void set(int index, String value) {
items.add(index, value);
}
}
```

`Iterator` 类:

```java
public abstract class Iterator {
public abstract Object first();
public abstract Object next();
public abstract boolean isDone();
public abstract Object currentItem();
}
```

**代码实现**
`ConcreteIterator` 类:

- C++ 实现:[链接](https://github.com/datawhalechina/sweetalk-design-pattern/tree/main/src/design_patterns/cpp/iterator)
- Java 实现:[链接](https://github.com/datawhalechina/sweetalk-design-pattern/tree/main/src/design_patterns/java/iterator)
- Python 实现:[链接](https://github.com/datawhalechina/sweetalk-design-pattern/tree/main/src/design_patterns/python/iterator)
```java
public class ConcreteIterator extends Iterator {
private ConcreteAggregate aggregate;
private int current = 0;

## 使用场景
public ConcreteIterator(ConcreteAggregate aggregate) {
this.aggregate = aggregate;
}

**适合场景**
@Override
public Object first() {
return aggregate.get(0);
}

- 当需要遍历访问一个聚合对象,而且不管这些对象是什么。
@Override
public Object next() {
Object ret = null;
current++;
if(current < aggregate.Count()) {
ret = aggregate.get(current);
}
return ret;
}

@Override
public boolean isDone() {
return current >= aggregate.Count();
}

@Override
public Object currentItem() {
return aggregate.get(current);
}
}
```

`Main` 方法:

```java
public class Main {
public static void main(String[] args) {
ConcreteAggregate a = new ConcreteAggregate();
a.set(0, "大鸟");
a.set(1,"小菜");
a.set(2,"行李");
a.set(3,"老外");
a.set(4,"公交内部员工");
a.set(5,"小偷");

Iterator i = new ConcreteIterator(a);

while (!i.isDone()){
System.out.println(i.currentItem() + " 请买车票");
i.next();
}
}
}
```

执行结果:

```bash
大鸟 请买车票
小菜 请买车票
行李 请买车票
老外 请买车票
公交内部员工 请买车票
小偷 请买车票
```

### 结构组成

![](img/iterator/iterator.jpg)

- 聚集抽象类(Aggregate)。
- 具体聚集类(ConcreteAggregate)。
- 迭代抽象类(Iterator):用于定义各种行为的抽象方法,统一接口。
- 具体迭代器类(ConcreteIterator):继承 Iterator,实现具体行为的方法。

## 模式评价

### 适用场景

- 当需要遍历访问一个聚集对象,而且不管这些对象是什么。
- 内部结构复杂,只提供精简的访问方式。
- 对聚合对象支持多种方式遍历
- 对聚集对象支持多种方式遍历

**实际应用**
### 实际应用

- 列表、队列等容器。
- 字符串序列。

## 模式评价
### 优点缺点

**模式优点**
迭代器模式优点包括:

- 减少重复遍历代码。
- 存储与遍历分离。
- 简化数据访问方式。

**不足之处**
迭代器模式缺点包括:

- 过于简单的集合会增加复杂性。
- 增加新的聚合类时可能需要新的迭代器
- 增加新的聚集类时可能需要新的迭代器

0 comments on commit cf23e60

Please sign in to comment.