希赛考试网
首页 > 软考 > 软件设计师

迭代器模式实例

希赛网 2024-06-08 18:23:06

迭代器模式(Iterator Pattern)是一种行为型设计模式,它允许客户端逐步访问聚合对象的元素,而不暴露其底层表现形式。本文将从定义、结构和实现等多个角度介绍迭代器模式,并提供一个实例来说明它的用法。

定义

迭代器模式定义了一种方法,通过它可以顺序地访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部结构。它通过提供一个迭代器来实现该功能,该迭代器可以按需生成聚合对象的下一个元素。在软件开发中,在一个聚合对象有不同表现形式的情况下,可以使用迭代器模式抽象出它们的共性,并分离它们的变化和不变化的部分。

结构

迭代器模式的核心是迭代器(Iterator),它抽象出所有迭代器的共性操作:

```

abstract class Iterator {

abstract boolean hasNext();

abstract Object Next();

}

```

聚合对象(Aggregate)定义了创建迭代器的接口:

```

interface Aggregate {

Iterator createIterator();

}

```

具体聚合对象(Concrete Aggregate)实现了创建迭代器的接口,并存储其元素以供迭代器访问:

```

class ConcreteAggregate implements Aggregate {

private Object[] elements;

ConcreteAggregate(Object[] elements) {

this.elements = elements;

}

@Override

public Iterator createIterator() {

return new ConcreteIterator(this);

}

Object getElement(int index) {

return elements[index];

}

int size() {

return elements.length;

}

}

```

具体迭代器(Concrete Iterator)实现了迭代器接口,并持有对聚合对象的引用:

```

class ConcreteIterator extends Iterator {

private ConcreteAggregate aggregate;

private int index;

ConcreteIterator(ConcreteAggregate aggregate) {

this.aggregate = aggregate;

this.index = 0;

}

@Override

boolean hasNext() {

return index < aggregate.size();

}

@Override

Object Next() {

if (hasNext()) {

return aggregate.getElement(index++);

}

return null;

}

}

```

实现

现在,我们假设要实现一个文件浏览器,可以遍历一个文件夹中的所有文件。我们可以借助迭代器模式来实现该功能。首先,我们需要定义一个聚合对象抽象类,它可以是文件或文件夹:

```

abstract class FileSystemItem {

protected String name;

FileSystemItem(String name) {

this.name = name;

}

abstract void add(FileSystemItem item);

abstract void remove(FileSystemItem item);

abstract Iterator createIterator();

}

```

对于文件夹,它可以包含多个文件或文件夹:

```

class Folder extends FileSystemItem {

private List items;

Folder(String name) {

super(name);

items = new ArrayList<>();

}

@Override

void add(FileSystemItem item) {

items.add(item);

}

@Override

void remove(FileSystemItem item) {

items.remove(item);

}

@Override

Iterator createIterator() {

return new FolderIterator(this);

}

// ...

}

```

对于文件,它可以直接遍历:

```

class File extends FileSystemItem {

File(String name) {

super(name);

}

@Override

void add(FileSystemItem item) {

// do nothing

}

@Override

void remove(FileSystemItem item) {

// do nothing

}

@Override

Iterator createIterator() {

return new NullIterator();

}

// ...

}

```

接下来,我们实现一个具体迭代器来遍历文件夹:

```

class FolderIterator extends Iterator {

private Folder folder;

private int index;

private Iterator subIterator;

FolderIterator(Folder folder) {

this.folder = folder;

index = 0;

subIterator = null;

}

@Override

boolean hasNext() {

if (subIterator != null && subIterator.hasNext()) {

return true;

}

if (index < folder.getItems().size()) {

FileSystemItem item = folder.getItems().get(index);

if (item instanceof Folder) {

subIterator = ((Folder) item).createIterator();

return hasNext();

} else {

index++;

return true;

}

}

return false;

}

@Override

Object Next() {

if (hasNext()) {

if (subIterator != null && subIterator.hasNext()) {

return subIterator.Next();

} else {

FileSystemItem item = folder.getItems().get(index);

index++;

return item;

}

}

return null;

}

}

```

如果文件夹中包含了另一个文件夹,遍历器就会递归地访问其中的文件和文件夹。如果只有文件,迭代器只需要返回它本身即可。此外,我们还需要实现一个空迭代器,用于遍历文件:

```

class NullIterator extends Iterator {

@Override

boolean hasNext() {

return false;

}

@Override

Object Next() {

return null;

}

}

```

通过这些类的组合和迭代器的遍历,我们可以实现文件浏览器的遍历功能。

扫码咨询 领取资料


软考.png


软件设计师 资料下载
备考资料包大放送!涵盖报考指南、考情深度解析、知识点全面梳理、思维导图等,免费领取,助你备考无忧!
立即下载
软件设计师 历年真题
汇聚经典真题,展现考试脉络。精准覆盖考点,助您深入备考。细致解析,助您查漏补缺。
立即做题

软考资格查询系统

扫一扫,自助查询报考条件