设计模式之迭代器模式(Iterator Pattern)
文章目录
- 一、迭代器模式的定义与特点
- 二、角色与UML类图
- 2.1、 代码:
- 1、 Iterator
- 2、 ConcreteIterator
- 3、 Aggregate
- 4、 ConcreteAggregate
- 5、 Client
- 三、大学-学院-专业的示例
- 3.1、需求
- 3.2、UML类图
- 3.3、代码
- 1、IteratorForComputerCollege(计算机学院迭代器)
- 2、IteratorForInfoColleage(信息工程学院迭代器)
- 3、Department(元素)
- 4、Aggregate(聚合接口)
- 4、AggregateForComputerCo(计算机学院聚合)
- 5、AggregateForInfoCo(信息工程学院聚合实现类)
- 6、OutPutImpl(输出类)
- 7、Client
- 四、迭代器模式在JDK中应用
- 4.1、分析 ArrayList 使用迭代器模式
- 4.2、分析 LinkedList 使用迭代器模式
- 4.2.1、LinkedList.java
- 4.2.2、AbstractSequentialList.java
- 4.2.2、AbstractList.java
在程序设计中,经常要访问一个聚合对象中的各个元素,如数据结构中的链表进行遍历,通常的做法是将链表的创建和遍历都放在同一个类中,但这种方式不利于程序的扩展,如果要更换遍历方法就必须修改程序源代码,这违背了 “开闭原则”。
既然将遍历方法封装在聚合类中不可取,那么聚合类中不提供遍历方法,将遍历方法由用户自己实现是否可行呢?答案是同样不可取,因为这种方式会存在两个缺点:
- 暴露了聚合类的内部表示,使其数据不安全;
- 增加了客户的负担。
“迭代器模式”能较好地克服以上缺点,它在客户访问类与聚合类之间插入一个迭代器,这分离了聚合对象与其遍历行为,对客户也隐藏了其内部细节,且满足“单一职责原则”和“开闭原则”,如 Java 中的 Collection、List、Set、Map 等都包含了迭代器。
一、迭代器模式的定义与特点
定义:提供一个对象
来顺序访问 聚合对象
中的一系列数据,而不暴露 聚合对象
的内部表示。
迭代器模式是一种对象行为型模式。
优点:
- 访问一个聚合对象的内容而无须暴露它的内部表示。
- 遍历任务交由迭代器完成,这简化了聚合类。
- 它支持以不同方式遍历一个聚合,甚至可以自定义迭代器的子类以支持新的遍历。
- 增加新的聚合类和迭代器类都很方便,无须修改原有代码。
- 封装性良好,为遍历不同的聚合结构提供一个统一的接口。
缺点:
每个聚合对象都要一个迭代器,迭代器(类)数量太多时就不好管理。
二、角色与UML类图
迭代器模式有两个主要角色,一个是 迭代器
对象,能遍历对象;另一个是聚合对象,没有遍历对象功能,但内嵌一个 迭代器
对象,通过 迭代器
来完成其内部对象的遍历。
迭代器模式的角色:
Iterator
( 迭代器接口):定义访问和遍历聚合元素的接口,通常包含 hasNext()、first()、next() 等方法。Concretelterator
(具体迭代器
):实现Iterator
中所定义的方法,完成对ConcreteAggregate
的遍历,记录遍历的当前位置。Aggregate
(聚合接口):定义存储、添加、删除元素
、Iterator
的接口。ConcreteAggregate
(具体聚合器
):实现Aggregate
定义的方法,返回一个Concretelterator
(迭代器
) 的实例。
2.1、 代码:
1、 Iterator
/** * 迭代器 */
public interface Iterator {
Object first();
Object next();
boolean hasNext();
}
2、 ConcreteIterator
import java.util.List;
/** * 具体迭代器 */
public class ConcreteIterator implements Iterator {
private List<Object> list = null;
private int index = -1;
public ConcreteIterator(List<Object> list) {
this.list = list;
}
public boolean hasNext() {
if (index < list.size() - 1) {
return true;
} else {
return false;
}
}
public Object first() {
index = 0;
Object obj = list.get(index);
return obj;
}
public Object next() {
Object obj = null;
if (this.hasNext()) {
obj = list.get(++index);
}
return obj;
}
}
3、 Aggregate
/** * 聚合接口 */
public interface Aggregate {
public void add(Object obj);
public void remove(Object obj);
public Iterator getIterator();
}
4、 ConcreteAggregate
import java.util.ArrayList;
import java.util.List;
/** * 具体聚合 */
public class ConcreteAggregate implements Aggregate {
private List<Object> list = new ArrayList<Object>();
public void add(Object obj) {
list.add(obj);
}
public void remove(Object obj) {
list.remove(obj);
}
public Iterator getIterator() {
return (new ConcreteIterator(list));
}
}
5、 Client
public class Client {
public static void main(String[] args) {
Aggregate ag = new ConcreteAggregate();
ag.add("中山大学");
ag.add("华南理工");
ag.add("韶关学院");
System.out.print("聚合的内容有:");
Iterator it = ag.getIterator();
while (it.hasNext()) {
Object ob = it.next();
System.out.println(ob.toString());
}
System.out.println("\n==========================");
Object ob = it.first();
System.out.println("First:" + ob.toString());
}
}
输出结果:
聚合的内容有:中山大学
华南理工
韶关学院
==========================
First:中山大学
三、大学-学院-专业的示例
3.1、需求
需求是在一个页面中展示大学里学院和其开设的专业。
分析:大学 —> 学院 —> 专业的关系图如下:
3.2、UML类图
3.3、代码
1、IteratorForComputerCollege(计算机学院迭代器)
import java.util.Iterator;
/** * 具体迭代器(计算机学院迭代器) */
public class IteratorForComputerCollege implements Iterator {
// 这里我们需要Department 是以怎样的方式存放=>数组
Department[] departments;
int position = 0; // 遍历的位置
public IteratorForComputerCollege(Department[] departments) {
this.departments = departments;
}
// 判断是否还有下一个元素
@Override
public boolean hasNext() {
if (position >= departments.length || departments[position] == null) {
return false;
} else {
return true;
}
}
@Override
public Object next() {
Department department = departments[position];
position += 1;
return department;
}
// 删除的方法,默认空实现
public void remove() {
}
}
2、IteratorForInfoColleage(信息工程学院迭代器)
import java.util.Iterator;
import java.util.List;
/** * 具体迭代器(信息工程学院迭代器) */
public class IteratorForInfoColleage implements Iterator {
List<Department> departmentList; // 信息工程学院是以List方式存放系
int index = -1;//索引
public IteratorForInfoColleage(List<Department> departmentList) {
this.departmentList = departmentList;
}
//判断list中还有没有下一个元素
@Override
public boolean hasNext() {
if(index >= departmentList.size() - 1) {
return false;
} else {
index += 1;
return true;
}
}
@Override
public Object next() {
return departmentList.get(index);
}
//空实现remove
public void remove() {
}
}
3、Department(元素)
public class Department {
private String name;
private String desc;
public Department(String name, String desc) {
super();
this.name = name;
this.desc = desc;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
4、Aggregate(聚合接口)
import java.util.Iterator;
/** * 聚合接口 */
public interface Aggregate {
public String getName();
//增加系的方法
public void addDepartment(String name, String desc);
//返回一个迭代器,遍历
public Iterator createIterator();
}
4、AggregateForComputerCo(计算机学院聚合)
import java.util.Iterator;
/** * 聚合实现类(计算机学院聚合) */
public class AggregateForComputerCo implements Aggregate {
Department[] departments;
int numOfDepartment = 0 ;// 保存当前数组的对象个数
public AggregateForComputerCo() {
departments = new Department[5];
addDepartment("Java专业", " Java专业 ");
addDepartment("PHP专业", " PHP专业 ");
addDepartment("大数据专业", " 大数据专业 ");
}
@Override
public String getName() {
return "计算机学院";
}
@Override
public void addDepartment(String name, String desc) {
Department department = new Department(name, desc);
departments[numOfDepartment] = department;
numOfDepartment += 1;
}
@Override
public Iterator createIterator() {
return new IteratorForComputerCollege(departments);
}
}
5、AggregateForInfoCo(信息工程学院聚合实现类)
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/** * 聚合实现类(信息工程学院聚合实现类) */
public class AggregateForInfoCo implements Aggregate {
List<Department> departmentList;
public AggregateForInfoCo() {
departmentList = new ArrayList<Department>();
addDepartment("信息安全专业", " 信息安全专业 ");
addDepartment("网络安全专业", " 网络安全专业 ");
addDepartment("服务器安全专业", " 服务器安全专业 ");
}
@Override
public String getName() {
return "信息工程学院";
}
@Override
public void addDepartment(String name, String desc) {
Department department = new Department(name, desc);
departmentList.add(department);
}
@Override
public Iterator createIterator() {
return new IteratorForInfoColleage(departmentList);
}
}
6、OutPutImpl(输出类)
import java.util.Iterator;
import java.util.List;
public class OutPutImpl {
//学院集合
List<Aggregate> collegeList;
public OutPutImpl(List<Aggregate> collegeList) {
this.collegeList = collegeList;
}
//遍历所有学院,然后调用printDepartment 输出各个学院的系
public void printCollege() {
//从collegeList 取出所有学院, Java 中的 List 已经实现Iterator
Iterator<Aggregate> iterator = collegeList.iterator();
while(iterator.hasNext()) {
//取出一个学院
Aggregate college = iterator.next();
System.out.println("=== "+college.getName() +"=====" );
printDepartment(college.createIterator()); //得到对应迭代器
}
}
//输出 学院输出 系
public void printDepartment(Iterator iterator) {
while(iterator.hasNext()) {
Department d = (Department)iterator.next();
System.out.println(d.getName());
}
}
}
7、Client
import java.util.ArrayList;
import java.util.List;
public class Client {
public static void main(String[] args) {
// 创建学院
List<Aggregate> collegeList = new ArrayList<Aggregate>();
// 计算机学院
AggregateForComputerCo computerCollege = new AggregateForComputerCo();
// 信息学院
AggregateForInfoCo infoCollege = new AggregateForInfoCo();
collegeList.add(computerCollege);
collegeList.add(infoCollege);
// 输出
OutPutImpl outPutImpl = new OutPutImpl(collegeList);
outPutImpl.printCollege();
}
}
输出:
=== 计算机学院=====
Java专业
PHP专业
大数据专业
=== 信息工程学院=====
信息安全专业
网络安全专业
服务器安全专业
四、迭代器模式在JDK中应用
4.1、分析 ArrayList 使用迭代器模式
4.2、分析 LinkedList 使用迭代器模式
4.2.1、LinkedList.java
4.2.2、AbstractSequentialList.java
AbstractSequentialList 是 LinkedList 的父类。
4.2.2、AbstractList.java
AbstractList 是 AbstractSequentialList的父类。
还没有评论,来说两句吧...