迭代器模式

示例1

以学院及部门为例。学院有计算机学院和信息工程学院,而两者的内部存储方式并不同,一个是用数组存储部门,一个是List存储部门,这是如果想要获取不同学院的部门,传统模式将存储和遍历放在一起,导致类职责过重,违反“单一职责原则”。将学院抽象出接口,导致接口中方法过多,违反了“接口隔离原则”

  • 部门
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;
    }
}
  • 学院接口
public interface ICollege {

    String getName();

    void addDepartment(String name);

    Iterator createIterator();
}
  • 计算机学院
public class ComputerCollege implements ICollege {

    Department[] departments = new Department[2];
    int totalOfDepartment = 0 ;

    @Override
    public String getName() {
        return "计算机学院";
    }

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

    @Override
    public Iterator createIterator() {
        return new ComputerCollegeIterator(departments);
    }
}
  • 信息工程学院
public class InfoCollege implements ICollege {

    List<Department> departmentList = new ArrayList<>(2);

    @Override
    public String getName() {
        return "信息工程学院";
    }

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

    @Override
    public Iterator createIterator() {
        return new InfoColleageIterator(departmentList);
    }
}
  • 计算机Iterator
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() {
        return departments[index++];
    }
}
  • 信息工程Iterator
public class InfoColleageIterator implements Iterator {

    private List<Department> departmentList;
    int index = -1;

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

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

    @Override
    public Object next() {
        return departmentList.get(index);
    }
}
  • 获取信息类
public class CollegeInfo {
    private List<ICollege> collegeList;

    public CollegeInfo(List<ICollege> collegeList) {
        this.collegeList = collegeList;
    }

    public void getCollegeInfo() {
        Iterator<ICollege> iterator = collegeList.iterator();
        ICollege college;
        while (iterator.hasNext()) {
            college = iterator.next();
            System.out.println("--- " + college.getName() + " ---");
            // 打印学院下面的department
            getDepartInfo(college.createIterator());
        }
    }

    private void getDepartInfo(Iterator iterator) {
        Department department;
        while (iterator.hasNext()) {
            department = (Department) iterator.next();
            System.out.println(department.getName());;
        }
    }

}
  • 测试类
public class Iterator01Test {
    public static void main(String[] args) {
        ArrayList<ICollege> colleges = new ArrayList<>(2);

        ComputerCollege computerCollege = new ComputerCollege();
        computerCollege.addDepartment("软件工程");
        computerCollege.addDepartment("大数据");

        InfoCollege infoCollege = new InfoCollege();
        infoCollege.addDepartment("信息安全");
        infoCollege.addDepartment("网络安全");

        colleges.add(computerCollege);
        colleges.add(infoCollege);

        CollegeInfo collegeInfo = new CollegeInfo(colleges);
        collegeInfo.getCollegeInfo();

        /**
         * --- 计算机学院 ---
         * 软件工程
         * 大数据
         * --- 信息工程学院 ---
         * 信息安全
         * 网络安全
         */

    }
}
总结
  • 优点
    • 提供一个统一的方法遍历对象,客户不用再考虑聚合的类型,使用一种方法就可以遍历对象了
    • 隐藏了聚合的内部结构,客户端要遍历聚合的时候只能取到迭代器,而不会知道聚合的具体组成
    • 迭代器简化了聚合类。由于引入了迭代器,在原有的聚合对象中不需要再自行提供数据遍历等方法,这样可以简化聚合类的设计
    • 在迭代器模式中,由于引入了抽象层,增加新的聚合类和迭代器类都很方便,无须修改原有代码,满足“开闭原则”的要求
  • 缺点

    • 产生很多的迭代器类,不好维护
  • 适用场景
    • 需要遍历一组相似对象或者相同对象时
    • 需要隐藏对象的内部实现时
    • 需要为一个对象提供多种遍历方式时
12-22 12:01