前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >详解设计模式:迭代器模式

详解设计模式:迭代器模式

作者头像
栗筝i
发布2022-12-05 08:29:51
4970
发布2022-12-05 08:29:51
举报
文章被收录于专栏:迁移内容

迭代器模式(Iterator Pattern)也被称为游标模式(Cursor Pattern),是在 GoF 23 种设计模式中定义了的行为型模式。是一种最简单也最常见的设计模式。 迭代器模式 可以让用户透过特定的接口巡访容器中的每一个元素而不用了解底层的实现。 ~ 本篇文章内容包括:关于迭代器模式、观察者模式 Demo、模版方法模式的应用(ArrayList/Iterator 中的迭代器模式)


文章目录


一、关于迭代器模式

1、关于迭代器模式

迭代器模式(Iterator Pattern)也被称为游标模式(Cursor Pattern),是在 GoF 23 种设计模式中定义了的行为型模式。是一种最简单也最常见的设计模式。

迭代器模式 可以让用户透过特定的接口巡访容器中的每一个元素而不用了解底层的实现。

迭代器模式 提供一种方法顺序访问一个聚合(指一组对象的组合结构,如:Java中的集合、数组等)对象中各个元素,而又不需暴露该对象的内部表示。迭代器模式的本质:控制访问聚合对象中的元素。其设计意图:无须暴露聚合对象的内部实现,就能够访问到聚合对象中的各个元素。

2、关于迭代器模式的构成

迭代器模式主要包含以下 4 种角色:

  • 抽象聚合(Aggregate)角色:定义存储、添加、删除聚合元素以及创建迭代器对象的接口。
  • 具体聚合(ConcreteAggregate)角色:实现抽象聚合类,返回一个具体迭代器的实例。
  • 抽象迭代器(Iterator)角色:定义访问和遍历聚合元素的接口,通常包含 hasNext()、next() 等方法。
  • 具体迭代器(Concretelterator)角色:实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历,记录遍历的当前位置。
3、关于迭代器模式的XML
4、关于迭代器模式的适用场景
  • 内容保密 : 访问 集合对象 的内容 , 无需暴露内部表示 ;
  • 统一接口 : 为遍历 不同的 集合结构 , 提供统一接口。
5、关于迭代器模式的优缺点

迭代器模式优点

  • 分离了集合对象的遍历行为;
  • 抽象出了迭代器负责集合对象的遍历 , 可以让外部的代码透明的访问集合内部的数据 ;

迭代器模式缺点

  • 类的个数成对增加;
  • 迭代器模式,将存储数据 , 遍历数据两个职责拆分 ;
  • 如果新添加一个 集合类 , 需要增加该 集合类 对应的 迭代器类 , 类的个数成对增加 , 在一定程度上 , 增加了系统复杂性 ;

二、观察者模式 Demo

1、Demo 设计

定义一个可以存储学生对象的容器对象,将遍历该容器的功能交由迭代器实现。

Demo 类图如下:

2、Demo 实现

# Student 元素类

代码语言:javascript
复制
public class Student {

    private String name;

    private String number;

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", number='" + number + '\'' +
                '}';
    }

    /**
     * 建造者类构造函数
     *
     * @param builder Builder
     */
    private Student(Builder builder) {
        name = builder.name;
        number = builder.number;
    }

    /**
     * 建造者类
     */
    public static final class Builder {

        private String name;

        private String number;

        public Builder() {
        }

        public Builder name(String val) {
            name = val;
            return this;
        }

        public Builder number(String val) {
            number = val;
            return this;
        }

        public Student build() {
            return new Student(this);
        }
    }
}

# StudentAggregate 抽象聚合(Aggregate)角色

代码语言:javascript
复制
public interface StudentAggregate {
    
    /**
     * 添加元素
     * @param student Student
     */
    void addStudent(Student student);

    /**
     * 删除元素
     * @param student Student
     */
    void removeStudent(Student student);

    /**
     * 获取迭代器对象
     * @return StudentIterator
     */
    StudentIterator getStudentIterator();
}

# StudentAggregateImpl 具体聚合(ConcreteAggregate)角色

代码语言:javascript
复制
import java.util.ArrayList;
import java.util.List;

public class StudentAggregateImpl implements StudentAggregate {

    /**
     * 学生列表
     */
    private final List<Student> list = new ArrayList<Student>();

    @Override
    public void addStudent(Student student) {
        this.list.add(student);
    }

    @Override
    public void removeStudent(Student student) {
        this.list.remove(student);
    }

    @Override
    public StudentIterator getStudentIterator() {
        return new StudentIteratorImpl(list);
    }
    
}

# StudentIterator 抽象迭代器(Iterator)角色

代码语言:javascript
复制
public interface StudentIterator {

    /**
     * 判断是否还有下一个元素
     * @return boolean
     */
    boolean hasNext();

    /**
     * 获取下一个元素
     * @return Student
     */
    Student next();
}

# StudentIteratorImpl 具体迭代器(Concretelterator)角色

代码语言:javascript
复制
import java.util.List;

public class StudentIteratorImpl implements StudentIterator {

    private final List<Student> list;
    private int position = 0;

    public StudentIteratorImpl(List<Student> list) {
        this.list = list;
    }

    @Override
    public boolean hasNext() {
        return position < list.size();
    }

    @Override
    public Student next() {
        Student currentStudent = list.get(position);
        position ++;
        return currentStudent;
    }
}
3、Demo 测试
代码语言:javascript
复制
public class Client {

    public static void main(String[] args) {
        
        // 抽象聚合类-StudentAggregate 具体聚合类-StudentAggregateImpl
        StudentAggregate studentAggregate = new StudentAggregateImpl();
        // 建造者模式构造元素
        studentAggregate.addStudent(new Student.Builder().name("小明").number("1001").build());
        studentAggregate.addStudent(new Student.Builder().name("小红").number("1002").build());
        // 通过 具体聚合类 获取 具体迭代器
        StudentIterator iterator = studentAggregate.getStudentIterator();
        
        // 迭代器遍历
        while (iterator.hasNext()){
            System.out.println(iterator.next().toString());
        }
    }
}

三、模版方法模式的应用(ArrayList/Iterator 中的迭代器模式)

Java 代码中关于 List 的迭代器使用:

代码语言:javascript
复制
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class IteratorDemo {

    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("AA");
        list.add("BB");
        list.add("CC");
        
        // list.iterator() 方法返回的肯定是 Iterator 接口的子实现类对象
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}

其中,List-抽象聚合类、ArrayList-具体的聚合类、Iterator-抽象迭代器、list.iterator() 返回的是实现了 Iterator 接口的具体迭代器对象。

# ArrayList 的源码对于迭代器部分的实现:

代码语言:javascript
复制
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, Serializable {
    
    public Iterator<E> iterator() {
        return new ArrayList.Itr();
    }
    
    
    private class Itr implements Iterator<E> {
      	// 下一个要返回元素的索引
        int cursor;       
      	// 上一个返回元素的索引
        int lastRet = -1; 
        int expectedModCount = modCount;

        Itr() {}
		
        //判断是否还有元素
        public boolean hasNext() {
            return cursor != size;
        }

        //获取下一个元素
        public E next() {
            checkForComodification();
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }
        ...
    }
}

可以看到:在 iterator 方法中返回了一个实例化的 Iterator 对象。Itr 是一个内部类,它实现了 Iterator 接口并重写了其中的抽象方法。

代码语言:javascript
复制
// List 集成自 Collection
public interface List<E> extends Collection<E>

// Collection 继承自 Iterable
public interface Collection<E> extends Iterable<E>

Ps:当我们在使用 Java 开发的时候,想使用迭代器模式的话,只要让我们自己定义的容器类实现 java.util.Iterable 并实现其中的 iterator() 方法使其返回一个 java.util.Iterator 的实现类就可以了。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-12-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 一、关于迭代器模式
    • 1、关于迭代器模式
      • 2、关于迭代器模式的构成
        • 3、关于迭代器模式的XML
          • 4、关于迭代器模式的适用场景
            • 5、关于迭代器模式的优缺点
            • 二、观察者模式 Demo
              • 1、Demo 设计
                • 2、Demo 实现
                  • 3、Demo 测试
                  • 三、模版方法模式的应用(ArrayList/Iterator 中的迭代器模式)
                  相关产品与服务
                  容器服务
                  腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档