通俗易懂设计模式(迭代器模式)

迭代器模式是一种行为型设计模式,它提供了一种遍历集合元素的统一接口,使得在不暴露集合内部结构的情况下可以顺序访问其中的每个元素。迭代器模式具有以下特点:

  1. 提供一种遍历集合元素的统一接口。
  2. 隐藏集合内部结构,客户端不需要关心集合的具体实现。
  3. 可以同时遍历多个集合,只要它们提供相同的迭代器接口。

迭代器模式的主要角色有:

  1. 迭代器(Iterator):定义遍历集合元素的接口,包括获取下一个元素、判断是否有下一个元素等方法。
  2. 具体迭代器(Concrete Iterator):实现迭代器接口,负责遍历集合的具体实现。
  3. 集合(Aggregate):定义创建迭代器的接口,即返回一个迭代器对象。
  4. 具体集合(Concrete Aggregate):实现集合接口,返回一个具体迭代器对象。

下面是一个使用 Java 实现的迭代器模式的例子:

java 复制代码
// 迭代器接口
interface Iterator {
    boolean hasNext();
    Object next();
}

// 具体迭代器
class ConcreteIterator implements Iterator {
    private ConcreteAggregate aggregate;
    private int current = 0;

    public ConcreteIterator(ConcreteAggregate aggregate) {
        this.aggregate = aggregate;
    }

    @Override
    public boolean hasNext() {
        return current< aggregate.size();
    }

    @Override
    public Object next() {
        if (hasNext()) {
            return aggregate.getElement(current++);
        }
        return null;
    }
}

// 集合接口
interface Aggregate {
    Iterator iterator();
}

// 具体集合
class ConcreteAggregate implements Aggregate {
    private Object[] elements;
    private int size = 0;

    public ConcreteAggregate(int size) {
        this.elements = new Object[size];
    }

    public void add(Object element) {
        if (size< elements.length) {
            elements[size++] = element;
        }
    }

    public Object getElement(int index) {
        return elements[index];
    }

    public int size() {
        return size;
    }

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

// 客户端
public class Client {
    public static void main(String[] args) {
        ConcreteAggregate aggregate = new ConcreteAggregate(5);
        aggregate.add("A");
        aggregate.add("B");
        aggregate.add("C");
        aggregate.add("D");
        aggregate.add("E");

        Iterator iterator = aggregate.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}

在这个例子中,我们定义了一个 ConcreteAggregate 类,它实现了 Aggregate 接口,并提供了一个 iterator() 方法来返回一个 ConcreteIterator 对象。ConcreteIterator 类实现了 Iterator 接口,并在其内部维护了一个指向 ConcreteAggregate 对象的引用,用于遍历集合中的元素。客户端可以通过调用 iterator() 方法获取迭代器对象,并使用迭代器的 hasNext() 和 next() 方法遍历集合中的元素。

迭代器模式的优点:

  1. 遍历集合元素时,不需要关心集合的内部结构,只需要关心迭代器的接口。
  2. 可以同时遍历多个集合,只要它们提供相同的迭代器接口。
  3. 可以在遍历过程中,对集合进行修改,而不会影响遍历的正确性。

迭代器模式的缺点:

  1. 需要为每个集合类提供一个具体的迭代器类,增加了代码的复杂性。
  2. 迭代器模式不支持并发访问,如果多个线程同时遍历同一个集合,可能会出现数据不一致的问题。

场景举例

场景一:遍历集合

迭代器模式是一种非常有用的设计模式,它提供了一种在不暴露集合内部结构的情况下,顺序访问集合中元素的方法。在实际开发中,我们经常需要遍历各种类型的集合,如数组、列表、栈、队列等。使用迭代器模式可以使代码更加简洁、灵活和可维护。

以遍历一个整数数组为例,我们可以使用迭代器模式来实现:

java 复制代码
public interface Iterator<T> {
    boolean hasNext();
    T next();
}

public class ArrayIterator<T> implements Iterator<T> {
    private T[] array;
    private int index;

    public ArrayIterator(T[] array) {
        this.array = array;
        index = 0;
    }

    @Override
    public boolean hasNext() {
        return index< array.length;
    }

    @Override
    public T next() {
        return array[index++];
    }
}

public class Array<T> {
    private T[] array;

    public Array(T[] array) {
        this.array = array;
    }

    public Iterator<T> iterator() {
        return new ArrayIterator<>(array);
    }
}

public class IteratorPatternDemo {
    public static void main(String[] args) {
        Integer[] numbers = {1, 2, 3, 4, 5};
        Array<Integer> integerArray = new Array<>(numbers);

        Iterator<Integer> iterator = integerArray.iterator();
        while (iterator.hasNext()) {
            System.out.print(iterator.next() + " ");
        }
    }
}

在这个例子中,我们定义了一个通用的迭代器接口 Iterator,它包含两个方法:hasNext() 和 next()。然后,我们为整数数组实现了一个具体的迭代器类 ArrayIterator,它实现了 Iterator 接口。最后,我们创建了一个 Array 类,它包含一个数组,并提供了一个 iterator() 方法,用于返回一个迭代器对象。

场景二:数据库查询

在数据库查询中,我们经常需要遍历查询结果集。使用迭代器模式可以使代码更加简洁、灵活和可维护。

以JDBC为例,我们可以使用迭代器模式来实现对数据库表的查询操作:

java 复制代码
public interface ResultSetIterator<T> extends Iterator<T> {
    void close();
}

public class ResultSetIteratorImpl<T> implements ResultSetIterator<T> {
    private ResultSet resultSet;
    private Class<T> entityClass;

    public ResultSetIteratorImpl(ResultSet resultSet, Class<T> entityClass) {
        this.resultSet = resultSet;
        this.entityClass = entityClass;
    }

    @Override
    public boolean hasNext() {
        try {
            return resultSet.next();
        } catch (SQLException e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public T next() {
        try {
            T entity = entityClass.newInstance();
            Field[] fields = entityClass.getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                String columnName = field.getName();
                Object value = resultSet.getObject(columnName);
                field.set(entity, value);
            }
            return entity;
        } catch (InstantiationException | IllegalAccessException | SQLException e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public void close() {
        try {
            resultSet.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

public class DatabaseAccessor {
    private Connection connection;

    public DatabaseAccessor(String url, String username, String password) {
        try {
            connection = DriverManager.getConnection(url, username, password);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public <T> Iterator<T> query(String sql, Class<T> entityClass) {
        try {
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            ResultSet resultSet = preparedStatement.executeQuery();
            return new ResultSetIteratorImpl<>(resultSet, entityClass);
        } catch (SQLException e) {
            e.printStackTrace();
            return null;
        }
    }

    public void close() {
        try {
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

public class IteratorPatternDemo {
    public static void main(String[] args) {
        DatabaseAccessor databaseAccessor = new DatabaseAccessor("jdbc:mysql://localhost:3306/test", "root", "password");
        String sql = "SELECT * FROM users";
        Iterator<User> iterator = databaseAccessor.query(sql, User.class);

        while (iterator.hasNext()) {
            User user = iterator.next();
            System.out.println(user);
        }

        databaseAccessor.close();
    }
}

在这个例子中,我们定义了一个通用的带关闭方法的迭代器接口 ResultSetIterator,它继承自 Iterator 接口。然后,我们为JDBC查询结果集实现了一个具体的迭代器类 ResultSetIteratorImpl,它实现了 ResultSetIterator 接口。最后,我们创建了一个 DatabaseAccessor 类,它包含了连接数据库和查询数据的方法,并提供了一个 query() 方法,用于返回一个迭代器对象。在 main() 方法中,我们演示了如何使用 DatabaseAccessor 类查询数据库表,并使用迭代器遍历查询结果集。

相关推荐
2301_780789662 小时前
跨平台适配!SDK 游戏盾兼容全终端游戏场景
java·网络·ddos
学长毕设3 小时前
基于springboot的食品仓库管理系统
java·spring boot·后端
步行cgn4 小时前
FormHttpMessageConverter 详解:Spring MVC 中表单数据的读写转换器
java·spring·mvc
龙亘川4 小时前
构建城市公共安全数字底座:亘川智城智慧安防系统全维度解读
java·大数据·开发语言·人工智能·信息可视化
金銀銅鐵4 小时前
[Java] 用 CLI 展示 EnumMap 增删键值对时的内部变化
java·源码·ai编程
秋天的怀念_David4 小时前
第二十二夜 · 数字迷雾
java·程序人生·算法
Raas1005 小时前
AI网关部署方案?从部署到上线全流程
java·开发语言·人工智能·gateway·ai网关·企业级ai网关·企业级ai产品
niucloud-admin5 小时前
NIUCLOUD PHP SAAS上门家政使用文档:城市管理
java·前端·php
霸道流氓气质6 小时前
智能客服组件:分层意图识别、RAG Advisor 与人工转接状态机的 Vue3 + Spring AI 生产级实战
java·人工智能·spring
captain3766 小时前
MyBatis操作数据库(入门2)
java·数据库·spring boot·后端·spring·mybatis