设计模式:019_迭代器模式

81 阅读3分钟

迭代器模式

迭代器模式,提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。

作用

  • 抽象出了迭代器负责聚合对象的遍历,可以让外部的代码透明的访问聚合内部的数据。
  • 分离了聚合对象的遍历行为,遍历任务交由迭代器完成,简化了聚合类。
  • 它支持以不同方式遍历一个聚合,甚至可以自定义迭代器的子类以支持新的遍历。
  • 增加新的聚合类和迭代器类都很方便,无须修改原有代码。
  • 封装性良好,为遍历不同的聚合结构提供一个统一的接口。

缺点

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

适用场景

  • 内容保密:访问集合对象的内容,无需暴露内部表示
  • 统一接口:为遍历不同的集合结构,提供统一接口

类图

迭代器模式类图.png

  • 抽象聚合(Aggregate)角色:定义存储、添加、删除聚合对象以及创建迭代器对象的接口。
  • 具体聚合(ConcreteAggregate)角色:实现抽象聚合类,返回一个具体迭代器的实例。
  • 抽象迭代器(Iterator)角色:定义访问和遍历聚合元素的接口,通常包含 hasNext()、next() 等方法。
  • 具体迭代器(ConcreteIterator)角色:实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历,记录遍历的当前位置。

代码表达

// 具体的数据元素
public class Department {
    private String name;

    public Department(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
// 抽象迭代器(Iterator)角色
public interface Iterator {
    boolean hasNext();
    Object next();
}
// 具体迭代器(ConcreteIterator)角色
public class ComputerCollegeIterator implements Iterator {
    // 元素以数组形式存储
    Department[] departments;
    int index = 0;

    public ComputerCollegeIterator(Department[] departments) {
        this.departments = departments;
    }

    @Override
    public boolean hasNext() {
        if (index >= departments.length || departments[index] == null) {
            return false;
        }
        return true;
    }

    @Override
    public Object next() {
        Department department = departments[index];
        index++;
        return department;
    }
}

public class InfoCollegeIterator implements Iterator {
    // 元素以集合形式存储
    List<Department> departmentList;
    int index = 0;

    public InfoCollegeIterator(List<Department> departmentList) {
        this.departmentList = departmentList;
    }

    @Override
    public boolean hasNext() {
        if (index > departmentList.size() - 1) {
            return false;
        }
        return true;
    }

    @Override
    public Object next() {
        Department department = departmentList.get(index);
        index++;
        return department;
    }
}
// 抽象聚合(Aggregate)角色
public interface College {
    String getName();

    void addDepartment(String name);

    Iterator createIterator();
}
// 具体聚合(ConcreteAggregate)角色
public class ComputerCollege implements College {
    // 元素以数组形式存储
    Department[] departments;
    int index = 0;

    public ComputerCollege() {
        departments = new Department[10];
    }

    @Override
    public String getName() {
        return "ComputerCollege";
    }

    @Override
    public void addDepartment(String name) {
        Department department = new Department(name);
        departments[index] = department;
        index++;
    }

    @Override
    public Iterator createIterator() {
        return new ComputerCollegeIterator(departments);
    }
}

public class InfoCollege implements College {
    // 元素以集合形式存储
    List<Department> departmentList;
    int index = 0;

    public InfoCollege() {
        departmentList = new ArrayList<>();
    }

    @Override
    public String getName() {
        return "InfoCollege";
    }

    @Override
    public void addDepartment(String name) {
        Department department = new Department(name);
        departmentList.add(department);
    }

    @Override
    public Iterator createIterator() {
        return new InfoCollegeIterator(departmentList);
    }
}

客户端调用

// 具体聚合类
ComputerCollege computerCollege = new ComputerCollege();
computerCollege.addDepartment("ComputerCollege-1");
computerCollege.addDepartment("ComputerCollege-2");
computerCollege.addDepartment("ComputerCollege-3");
// 具体聚合类
InfoCollege infoCollege = new InfoCollege();
infoCollege.addDepartment("InfoCollege-1");
infoCollege.addDepartment("InfoCollege-2");
infoCollege.addDepartment("InfoCollege-3");
// 迭代器遍历
List<College> collegeList = new ArrayList<>();
collegeList.add(computerCollege);
collegeList.add(infoCollege);
for (int i = 0; i < collegeList.size(); i++) {
    College college = collegeList.get(i);
    System.out.println("printCollege:" + college.getName());
    Iterator iterator = college.createIterator();
    while (iterator.hasNext()) {
        Department department = (Department) iterator.next();
        System.out.println(department.getName());
    }
}