设计模式之迭代器模式(Iterator Pattern)

╰半橙微兮° 2023-07-16 07:57 31阅读 0赞

文章目录

    • 一、迭代器模式的定义与特点
    • 二、角色与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

在程序设计中,经常要访问一个聚合对象中的各个元素,如数据结构中的链表进行遍历,通常的做法是将链表的创建和遍历都放在同一个类中,但这种方式不利于程序的扩展,如果要更换遍历方法就必须修改程序源代码,这违背了 “开闭原则”。

既然将遍历方法封装在聚合类中不可取,那么聚合类中不提供遍历方法,将遍历方法由用户自己实现是否可行呢?答案是同样不可取,因为这种方式会存在两个缺点:

  1. 暴露了聚合类的内部表示,使其数据不安全;
  2. 增加了客户的负担。

“迭代器模式”能较好地克服以上缺点,它在客户访问类与聚合类之间插入一个迭代器,这分离了聚合对象与其遍历行为,对客户也隐藏了其内部细节,且满足“单一职责原则”和“开闭原则”,如 Java 中的 Collection、List、Set、Map 等都包含了迭代器。

一、迭代器模式的定义与特点

定义:提供一个对象 来顺序访问 聚合对象 中的一系列数据,而不暴露 聚合对象 的内部表示。

迭代器模式是一种对象行为型模式。

优点:

  1. 访问一个聚合对象的内容而无须暴露它的内部表示。
  2. 遍历任务交由迭代器完成,这简化了聚合类。
  3. 它支持以不同方式遍历一个聚合,甚至可以自定义迭代器的子类以支持新的遍历。
  4. 增加新的聚合类和迭代器类都很方便,无须修改原有代码。
  5. 封装性良好,为遍历不同的聚合结构提供一个统一的接口。

缺点:

每个聚合对象都要一个迭代器,迭代器(类)数量太多时就不好管理。

二、角色与UML类图

迭代器模式有两个主要角色,一个是 迭代器 对象,能遍历对象;另一个是聚合对象,没有遍历对象功能,但内嵌一个 迭代器 对象,通过 迭代器 来完成其内部对象的遍历。

迭代器模式的角色:

  1. Iterator( 迭代器接口):定义访问和遍历聚合元素的接口,通常包含 hasNext()、first()、next() 等方法。
  2. Concretelterator(具体 迭代器):实现 Iterator 中所定义的方法,完成对 ConcreteAggregate 的遍历,记录遍历的当前位置。
  3. Aggregate(聚合接口):定义存储、添加、删除 元素Iterator 的接口。
  4. ConcreteAggregate(具体 聚合器 ):实现Aggregate 定义的方法,返回一个 Concretelterator迭代器) 的实例。

在这里插入图片描述

2.1、 代码:

1、 Iterator

  1. /** * 迭代器 */
  2. public interface Iterator {
  3. Object first();
  4. Object next();
  5. boolean hasNext();
  6. }

2、 ConcreteIterator

  1. import java.util.List;
  2. /** * 具体迭代器 */
  3. public class ConcreteIterator implements Iterator {
  4. private List<Object> list = null;
  5. private int index = -1;
  6. public ConcreteIterator(List<Object> list) {
  7. this.list = list;
  8. }
  9. public boolean hasNext() {
  10. if (index < list.size() - 1) {
  11. return true;
  12. } else {
  13. return false;
  14. }
  15. }
  16. public Object first() {
  17. index = 0;
  18. Object obj = list.get(index);
  19. return obj;
  20. }
  21. public Object next() {
  22. Object obj = null;
  23. if (this.hasNext()) {
  24. obj = list.get(++index);
  25. }
  26. return obj;
  27. }
  28. }

3、 Aggregate

  1. /** * 聚合接口 */
  2. public interface Aggregate {
  3. public void add(Object obj);
  4. public void remove(Object obj);
  5. public Iterator getIterator();
  6. }

4、 ConcreteAggregate

  1. import java.util.ArrayList;
  2. import java.util.List;
  3. /** * 具体聚合 */
  4. public class ConcreteAggregate implements Aggregate {
  5. private List<Object> list = new ArrayList<Object>();
  6. public void add(Object obj) {
  7. list.add(obj);
  8. }
  9. public void remove(Object obj) {
  10. list.remove(obj);
  11. }
  12. public Iterator getIterator() {
  13. return (new ConcreteIterator(list));
  14. }
  15. }

5、 Client

  1. public class Client {
  2. public static void main(String[] args) {
  3. Aggregate ag = new ConcreteAggregate();
  4. ag.add("中山大学");
  5. ag.add("华南理工");
  6. ag.add("韶关学院");
  7. System.out.print("聚合的内容有:");
  8. Iterator it = ag.getIterator();
  9. while (it.hasNext()) {
  10. Object ob = it.next();
  11. System.out.println(ob.toString());
  12. }
  13. System.out.println("\n==========================");
  14. Object ob = it.first();
  15. System.out.println("First:" + ob.toString());
  16. }
  17. }

输出结果:

  1. 聚合的内容有:中山大学
  2. 华南理工
  3. 韶关学院
  4. ==========================
  5. First:中山大学

三、大学-学院-专业的示例

3.1、需求

需求是在一个页面中展示大学里学院和其开设的专业。

分析:大学 —> 学院 —> 专业的关系图如下:

在这里插入图片描述

3.2、UML类图

在这里插入图片描述

3.3、代码

1、IteratorForComputerCollege(计算机学院迭代器)

  1. import java.util.Iterator;
  2. /** * 具体迭代器(计算机学院迭代器) */
  3. public class IteratorForComputerCollege implements Iterator {
  4. // 这里我们需要Department 是以怎样的方式存放=>数组
  5. Department[] departments;
  6. int position = 0; // 遍历的位置
  7. public IteratorForComputerCollege(Department[] departments) {
  8. this.departments = departments;
  9. }
  10. // 判断是否还有下一个元素
  11. @Override
  12. public boolean hasNext() {
  13. if (position >= departments.length || departments[position] == null) {
  14. return false;
  15. } else {
  16. return true;
  17. }
  18. }
  19. @Override
  20. public Object next() {
  21. Department department = departments[position];
  22. position += 1;
  23. return department;
  24. }
  25. // 删除的方法,默认空实现
  26. public void remove() {
  27. }
  28. }

2、IteratorForInfoColleage(信息工程学院迭代器)

  1. import java.util.Iterator;
  2. import java.util.List;
  3. /** * 具体迭代器(信息工程学院迭代器) */
  4. public class IteratorForInfoColleage implements Iterator {
  5. List<Department> departmentList; // 信息工程学院是以List方式存放系
  6. int index = -1;//索引
  7. public IteratorForInfoColleage(List<Department> departmentList) {
  8. this.departmentList = departmentList;
  9. }
  10. //判断list中还有没有下一个元素
  11. @Override
  12. public boolean hasNext() {
  13. if(index >= departmentList.size() - 1) {
  14. return false;
  15. } else {
  16. index += 1;
  17. return true;
  18. }
  19. }
  20. @Override
  21. public Object next() {
  22. return departmentList.get(index);
  23. }
  24. //空实现remove
  25. public void remove() {
  26. }
  27. }

3、Department(元素)

  1. public class Department {
  2. private String name;
  3. private String desc;
  4. public Department(String name, String desc) {
  5. super();
  6. this.name = name;
  7. this.desc = desc;
  8. }
  9. public String getName() {
  10. return name;
  11. }
  12. public void setName(String name) {
  13. this.name = name;
  14. }
  15. public String getDesc() {
  16. return desc;
  17. }
  18. public void setDesc(String desc) {
  19. this.desc = desc;
  20. }
  21. }

4、Aggregate(聚合接口)

  1. import java.util.Iterator;
  2. /** * 聚合接口 */
  3. public interface Aggregate {
  4. public String getName();
  5. //增加系的方法
  6. public void addDepartment(String name, String desc);
  7. //返回一个迭代器,遍历
  8. public Iterator createIterator();
  9. }

4、AggregateForComputerCo(计算机学院聚合)

  1. import java.util.Iterator;
  2. /** * 聚合实现类(计算机学院聚合) */
  3. public class AggregateForComputerCo implements Aggregate {
  4. Department[] departments;
  5. int numOfDepartment = 0 ;// 保存当前数组的对象个数
  6. public AggregateForComputerCo() {
  7. departments = new Department[5];
  8. addDepartment("Java专业", " Java专业 ");
  9. addDepartment("PHP专业", " PHP专业 ");
  10. addDepartment("大数据专业", " 大数据专业 ");
  11. }
  12. @Override
  13. public String getName() {
  14. return "计算机学院";
  15. }
  16. @Override
  17. public void addDepartment(String name, String desc) {
  18. Department department = new Department(name, desc);
  19. departments[numOfDepartment] = department;
  20. numOfDepartment += 1;
  21. }
  22. @Override
  23. public Iterator createIterator() {
  24. return new IteratorForComputerCollege(departments);
  25. }
  26. }

5、AggregateForInfoCo(信息工程学院聚合实现类)

  1. import java.util.ArrayList;
  2. import java.util.Iterator;
  3. import java.util.List;
  4. /** * 聚合实现类(信息工程学院聚合实现类) */
  5. public class AggregateForInfoCo implements Aggregate {
  6. List<Department> departmentList;
  7. public AggregateForInfoCo() {
  8. departmentList = new ArrayList<Department>();
  9. addDepartment("信息安全专业", " 信息安全专业 ");
  10. addDepartment("网络安全专业", " 网络安全专业 ");
  11. addDepartment("服务器安全专业", " 服务器安全专业 ");
  12. }
  13. @Override
  14. public String getName() {
  15. return "信息工程学院";
  16. }
  17. @Override
  18. public void addDepartment(String name, String desc) {
  19. Department department = new Department(name, desc);
  20. departmentList.add(department);
  21. }
  22. @Override
  23. public Iterator createIterator() {
  24. return new IteratorForInfoColleage(departmentList);
  25. }
  26. }

6、OutPutImpl(输出类)

  1. import java.util.Iterator;
  2. import java.util.List;
  3. public class OutPutImpl {
  4. //学院集合
  5. List<Aggregate> collegeList;
  6. public OutPutImpl(List<Aggregate> collegeList) {
  7. this.collegeList = collegeList;
  8. }
  9. //遍历所有学院,然后调用printDepartment 输出各个学院的系
  10. public void printCollege() {
  11. //从collegeList 取出所有学院, Java 中的 List 已经实现Iterator
  12. Iterator<Aggregate> iterator = collegeList.iterator();
  13. while(iterator.hasNext()) {
  14. //取出一个学院
  15. Aggregate college = iterator.next();
  16. System.out.println("=== "+college.getName() +"=====" );
  17. printDepartment(college.createIterator()); //得到对应迭代器
  18. }
  19. }
  20. //输出 学院输出 系
  21. public void printDepartment(Iterator iterator) {
  22. while(iterator.hasNext()) {
  23. Department d = (Department)iterator.next();
  24. System.out.println(d.getName());
  25. }
  26. }
  27. }

7、Client

  1. import java.util.ArrayList;
  2. import java.util.List;
  3. public class Client {
  4. public static void main(String[] args) {
  5. // 创建学院
  6. List<Aggregate> collegeList = new ArrayList<Aggregate>();
  7. // 计算机学院
  8. AggregateForComputerCo computerCollege = new AggregateForComputerCo();
  9. // 信息学院
  10. AggregateForInfoCo infoCollege = new AggregateForInfoCo();
  11. collegeList.add(computerCollege);
  12. collegeList.add(infoCollege);
  13. // 输出
  14. OutPutImpl outPutImpl = new OutPutImpl(collegeList);
  15. outPutImpl.printCollege();
  16. }
  17. }

输出:

  1. === 计算机学院=====
  2. Java专业
  3. PHP专业
  4. 大数据专业
  5. === 信息工程学院=====
  6. 信息安全专业
  7. 网络安全专业
  8. 服务器安全专业

四、迭代器模式在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的父类。
在这里插入图片描述

发表评论

表情:
评论列表 (有 0 条评论,31人围观)

还没有评论,来说两句吧...

相关阅读