Java设计模式之行为型-迭代器模式(UML类图+案例分析)

目录

一、基础概念

二、UML类图

三、角色设计

四、案例分析

五、总结


一、基础概念

迭代器模式是一种常用的设计模式,它主要用于遍历集合对象,提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。

举个简单的比喻,聚合对象像一个存放苹果的篮子,迭代器就像篮子边上的搬运工,专门负责把苹果一个一个取出来。客户端只需要找到搬运工,然后不停地让他取出苹果就可以了,而不需要关心篮子里面是怎么存放的。这样既方便客户端使用,也屏蔽了聚合对象内部的复杂性!

二、UML类图

Java设计模式之行为型-迭代器模式(UML类图+案例分析)_第1张图片

三、角色设计

角色 描述
抽象聚合角色 定义存创建、添加、获取等迭代器对象的接口
具体聚合角色 抽象聚合角色的实现类,返回一个具体迭代器实例
抽象迭代器角色 定义访问和遍历聚合元素的接口,通常包裹hashNext()和next()方法
具体迭代器角色 实现抽象迭代器接口中所定义的方法,完成聚合对象的遍历,记录遍历的当前为止
客户端角色 用于使用迭代器遍历聚合对象

四、案例分析

用迭代器模式模拟一个学生管理系统,主要内容如下:

1、定义Student类,表示学生信息。

2、定义StudentAggregate接口,作为学生集合的抽象接口。

3、实现StudentAggregateImpl类,具体的学生集合,使用List存储Student。

4、定义Iterator接口,规定迭代器的通用方法。

5、实现StudentIterator类,具体的学生迭代器。

6、在客户端代码中,通过迭代器遍历StudentAggregateImpl中的学生集合。

通过迭代器模式实现对学生集合的遍历,同时隐藏学生集合的具体实现细节,示例代码如下:

定义学生类:

public class Student {

  private String name;
  private int age;

  public Student(String name, int age) {
    this.name = name;
    this.age = age;
  }

  public String getName() {
    return name;
  }

  public int getAge() {
    return age;
  }
}

学生集合抽象聚合类:


public interface StudentAggregate {

  public Iterator createIterator();

  public int getNumberOfStudents();

  public Student getStudent(int index);

  public void addStudent(Student student);

}

学生集合具体聚合角色:

import java.util.ArrayList;
import java.util.List;

public class StudentAggregateImpl implements StudentAggregate{
  private List students;
  
  public StudentAggregateImpl() {
    students = new ArrayList<>();
  }

  @Override
  public Iterator createIterator() {
    return new StudentIterator(this);
  }  

  @Override
  public int getNumberOfStudents() {
    return students.size();
  }

  @Override
  public Student getStudent(int index) {
    return students.get(index);
  }

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

 抽象迭代器角色:

public interface Iterator {
  
  public boolean hasNext();

  public Student next();

}

学生具体迭代器角色:

public class StudentIterator implements Iterator {

  private StudentAggregate studentAggregate;
  private int index;

  public StudentIterator(StudentAggregate studentAggregate) {
    this.studentAggregate = studentAggregate;
  }

  @Override
  public boolean hasNext() {
    return (index < studentAggregate.getNumberOfStudents());
  }

  @Override
  public Student next() {
    return studentAggregate.getStudent(index++);
  }

}

客户端:

public class Client {

    public static void main(String[] args) {
        //使用示例
        StudentAggregate students = new StudentAggregateImpl();
        // 添加学生
        Student john = new Student("John", 18);
        Student mike = new Student("Mike", 18);
        students.addStudent(john);
        students.addStudent(mike);
        Iterator iterator = students.createIterator();
        while(iterator.hasNext()) {
            Student student = iterator.next();
            System.out.println(student.getName());
        }
    }
}

运行结果如下:

Java设计模式之行为型-迭代器模式(UML类图+案例分析)_第2张图片

这个迭代器模式在学生管理示例中的执行逻辑过程: 

1、定义Student类,用于表示学生信息。

2、定义StudentAggregate接口,作为抽象学生集合类,声明管理学生的通用方法。

3、实现StudentAggregateImpl类,具体的学生集合,使用List存储Student对象。

4、定义Iterator接口,规定迭代器的通用方法。

5、实现StudentIterator类,具体的学生迭代器,持有对StudentAggregate的引用。

6、创建StudentAggregateImpl对象students,表示具体的学生集合。

7、调用students的addStudent()方法,向集合中添加学生。

8、调用students的createIterator()方法,获取迭代器对象。

9、使用迭代器的hasNext()和next()方法遍历students集合,访问其中的学生对象。

10、在整个过程中,客户端代码都只与Iterator接口发生依赖,而不需了解学生集合的具体实现/

这样通过迭代器模式可以实现学生集合的遍历,同时也达到了对访问学生集合的控制和集合内部表示的封装。 

五、总结

优点:

1隔离了集合对象的遍历行为,抽象出一个迭代器类来负责迭代元素。

2提供了一种方法顺序访问一个聚合对象中的各个元素,而又无需暴露该对象的内部表示。

3迭代器简化了聚合类。客户端如果需要遍历聚合对象,只需要初始化一个迭代器,不需要知道聚合对象内部的具体实现。

4在同一个聚合类中可以定义多个遍历方式,通过不同的迭代器来实现。

5符合单一职责原则。

6实现了集合类的常用遍历算法,容易扩展和维护。

缺点:

1、增加了类的个数,代码复杂度会增加,需要维护更多的代码。

2、多态性能损耗。遍历时需要进行多次虚函数调用,遍历效率降低。

3、遍历算法复用性差。每次遍历都需要创建新的迭代器实例,无法重用已定义好的遍历算法。

应用场景:

1、访问一个聚合对象的内容而无需暴露它的内部表示。

2、为遍历不同的集合结构提供一个统一的接口(即支持多态迭代)。

3、提供一种方法顺序访问一个聚合对象中的各个元素,而又无需暴露该对象的内部表示。

4、分离集合对象的遍历行为到一个独立的迭代器类中。

符合的设计原则:

1、单一职责原则(Single Responsibility Principle)

迭代器模式将集合对象的遍历行为抽象到迭代器类中,集合类只负责存储,迭代器类只负责遍历。二者职责区分明确,符合单一职责原则。

2、开闭原则(Open Closed Principle)

可以在不修改集合类的情况下,定义新的迭代器类,满足扩展需求。增强了系统的可扩展性。

3、依赖倒转原则(Dependency Inversion Principle)

迭代器模式中,集合类和客户端都依赖于抽象迭代器接口,而不是依赖于具体迭代器类,倒转了依赖关系。

4、组合复用原则(Composite Reuse Principle)

客户端可以统一使用迭代器接口遍历不同的集合类,复用迭代器提供的遍历功能。

5、里氏替换原则(Liskov Substitution Principle)

迭代器模式中,每个迭代器类都可以通过继承迭代器接口,替换基类迭代器角色。

你可能感兴趣的:(Java,设计模式,java,设计模式,迭代器模式)