diff --git a/docs/content/design_pattern/iterator.md b/docs/content/design_pattern/iterator.md index ca398e1..c3f67d6 100644 --- a/docs/content/design_pattern/iterator.md +++ b/docs/content/design_pattern/iterator.md @@ -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 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,实现具体行为的方法。 + +## 模式评价 + +### 适用场景 + +- 当需要遍历访问一个聚集对象,而且不管这些对象是什么。 - 内部结构复杂,只提供精简的访问方式。 -- 对聚合对象支持多种方式遍历。 +- 对聚集对象支持多种方式遍历。 -**实际应用** +### 实际应用 - 列表、队列等容器。 - 字符串序列。 -## 模式评价 +### 优点缺点 -**模式优点** +迭代器模式优点包括: - 减少重复遍历代码。 - 存储与遍历分离。 - 简化数据访问方式。 -**不足之处** +迭代器模式缺点包括: - 过于简单的集合会增加复杂性。 -- 增加新的聚合类时可能需要新的迭代器。 \ No newline at end of file +- 增加新的聚集类时可能需要新的迭代器。 \ No newline at end of file