设计模式——迭代器模式
更多内容,前往 IT-BLOG
在程序设计中,经常需要访问一个聚合对象中的各个元素,例如:我们使用 list 存储元素,通常的做法是将 list 的创建和遍历放在同一个类中。但这种方法不利于扩展,如果将存储方式更改为数组时,就需要更换迭代方式。违背了 “开闭原则”。“迭代器模式” 能较好的克服以上缺点,它在客户访问类与聚合类之间插入一个迭代器,这分离了聚合对象与遍历行为,对客户也隐藏了其内部细节,满足 “单一职责原则” 和 “开闭原则”,如 Java 中的 Collection、List、Set、Map 等都包含迭代器。
一、迭代模式基本介绍
1)、迭代器模式(Iterator Pattern):是常用的设计模式,属于行为型模式。
2)、如果集合元素是通过不同的方式实现的,有数组、list 等等,当客户端要遍历这些集合元素的时候就要使用多种遍历方式,而且还会暴露元素的内部结构,可以考虑使用迭代器模式解决。
3)、迭代器模式,提供了一种遍历集合元素的统一接口,用一致的方法遍历结合元素,不需要知道集合对象的底层表示,即:不暴露其内部的结构。
4)、缺点:每个聚合对象都要一个迭代器,增加了类的个数,在一定程度上增加了系统的复杂度且不好管理。
5)、提供了一种设计思想,就是一个类应该只有一个引起变化的原因(叫做 “单一责任原则”)。在聚合类中,我们把迭代器分开,就是要把管理对象集合和遍历对象集合的责任分开,这样一来集合改变的话,只影响到聚合对象。而如果遍历方式改变的话,只影响到迭代器。
二、迭代器模式结构类图
迭代器模式是通过将聚合对象的遍历行为分离出来,抽象成迭代器类来实现的,其目的是在不暴露聚合对象的内部结构的情况下,让外部代码透明地访问聚合的内部数据。
迭代器模式主要包含以下角色:
【1】抽象聚合(Aggregate)角色:定义了存储、添加、删除聚合对象以及创建迭代对象的接口。
【2】具体聚合(ConcreteAggregate)角色:实现抽象聚合类,返回一个具体迭代器的实例。
【3】抽象迭代器(Iterator)角色:定义访问和遍历和聚合元素接口,通常包含 hasNext()、next()等方法。
【4】具体迭代器(ConcreteIterator)角色:实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历,记录遍历的当前位置。
三、迭代器模式案例分析
【1】抽象迭代器:使用 JDK 自带的 Iterator 接口,我们将源码粘贴过来,无需自行实现。子类需要实现 hasNext 和 next 方法
1 public interface Iterator<E> { 2 3 boolean hasNext(); 4 //使用泛型 E 5 E next(); 6 7 default void remove() { 8 throw new UnsupportedOperationException("remove"); 9 } 10 11 default void forEachRemaining(Consumer<? super E> action) { 12 Objects.requireNonNull(action); 13 while (hasNext()) 14 action.accept(next()); 15 } 16 }
【2】具体迭代器:定义将 List 集合包装为 Iterator 遍历的对象 ListIterator
分析一下 arrayList 的 iterator 的使用
【1】先了解下 ArrayList 的 Iterator 的使用:
【6】源码类图展示:同时多添加了两个具体的实现类:KeyIterator 与 LinkedList