天天看點

Java設計模式之疊代器模式1. 疊代器模式

目錄

  • 1. 疊代器模式
    • 1.1 定義、優缺點、适用場景
    • 1.2 模式的結構與實作

1. 疊代器模式

1.1 定義、優缺點、适用場景

定義:疊代器模式(Iterator Pattern)屬于行為型模式。如果我們的集合元素是用不同的方式實作的,有數組、集合類(ArrayList等)、其他方式,當用戶端要周遊這些集合元素的時候就要使用多種周遊方式,而且還會暴露元素的内部結構,可以考慮使用疊代器模式解決。其提供一種周遊集合元素的統一接口,用一緻的方法周遊集合元素,還不暴露集合元素的内部結構

優點:

  • 提供一個統一的方法周遊對象,客戶不用再考慮聚合的類型,使用一種方法就可以周遊對象了
  • 隐藏了聚合的内部結構,用戶端要周遊聚合的時候隻能取到疊代器,而不會知道聚合的具體組成
  • 提供了一種設計思想,就是一個類應該隻有一個引起變化的原因(叫做單一責任

    原則)。在聚合類中,我們把疊代器分開,就是要把管理對象集合和周遊對象集

    合的責任分開,這樣一來集合改變的話,隻影響到聚合對象。而如果周遊方式改變

    的話,隻影響到了疊代器

缺點:每個聚合對象都要一個疊代器,會生成多個疊代器不好管理類

适用場景:當要展示一組相似對象,或者周遊一組相同對象時使用

1.2 模式的結構與實作

結構:

  • 疊代器接口(Iterator):一般由

    java.util.Iterator

    提供(也可自己提供),含有hasNext、next、remove方法
  • 具體的疊代器類(ConcreteIterator):管理疊代
  • 統一的聚合接口(Aggregate):将用戶端和具體聚合解耦
  • 具體的聚合持有對象集合(ConcreteAggreage):提供一個方法,傳回一個疊代器,該疊代器可以正确周遊集合
  • 用戶端(Client):通過Iterator和Aggregate依賴子類

實作:

編寫程式展示一個學校院系結構。要在一個頁面中展示出學校的院系組成,一個學校有多個學院,一個學院有多個系。其中計算機學院的各個系是數組的元素,資訊工程學院的各個系是ArrayList的元素。使用疊代器進行解決

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

public class IteratorTest {

    public static void main(String[] args) {

        // 建立學院集合
        List<College> collegeList = new ArrayList<College>();

        ComputerCollege computerCollege = new ComputerCollege(6);
        InfoCollege infoCollege = new InfoCollege();

        collegeList.add(computerCollege);
        collegeList.add(infoCollege);

        OutPutImpl outPutImpl = new OutPutImpl(collegeList);
        outPutImpl.printCollege();
    }

}

// 學校的系
class Department {

    private String name;

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

    public String getName() {
        return this.name;
    }

}

// 疊代器接口
interface Iterator<E> {

    public boolean hasNext();

    public E next();

    public void remove();
}


// 具體的疊代器類-計算機學院的數組疊代器
class ComputerCollegeIterator implements Iterator<Department> {

    // 以數組的方式存放計算機學院的系
    private Department[] departments;
    // 預設周遊的位置
    private int position = 0;


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

    // 判斷是否還有下一個元素
    @Override
    public boolean hasNext() {
        if (this.position >= this.departments.length) {
            return false;
        } else {
            return true;
        }
    }

    @Override
    public Department next() {
        Department department = this.departments[this.position];
        this.position += 1;
        return department;
    }

    // 删除的方法,預設空實作
    public void remove() {

    }

}


// 具體的疊代器類-資訊學院的List疊代器
class InfoColleageIterator implements Iterator<Department> {

    // 以List的方式存放計算機學院的系
    private List<Department> departmentList;
    // 預設周遊的位置
    private int index = 0;


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

    // 判斷list中還有沒有下一個元素
    @Override
    public boolean hasNext() {
        if (this.index >= this.departmentList.size()) {
            return false;
        } else {
            return true;
        }
    }

    @Override
    public Department next() {
        Department department = this.departmentList.get(this.index);
        this.index += 1;
        return department;
    }

    // 删除的方法,雖然List有remove方法,但這裡提供空實作
    public void remove() {

    }

}


// 統一的聚合接口-學院
interface College {

    // 擷取學院的名稱
    public String getName();

    // 增加系的方法
    public void addDepartment(String name);

    // 傳回一個疊代器
    public Iterator createIterator();
}


// 具體的聚合持有對象集合-計算機學院
class ComputerCollege implements College {

    // 以數組的方式存放計算機學院的系,和ComputerCollegeIterator對應
    private Department[] departments;
    // 預設添加系到數組的位置
    private int positionOfDepartment = 0;


    public ComputerCollege(int DepartmentNum) {
        this.departments = new Department[DepartmentNum];
        this.addDepartment("大資料專業");
        this.addDepartment("Java專業");
        this.addDepartment("前端專業");
    }


    @Override
    public String getName() {
        return "計算機學院";
    }

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

    // 傳回一個計算機學院的系的疊代器
    @Override
    public Iterator createIterator() {
        return new ComputerCollegeIterator(this.departments);
    }

}


// 具體的聚合持有對象集合-資訊學院
class InfoCollege implements College {

    // 以List的方式存放資訊學院的系,和InfoCollegeIterator對應
    private List<Department> departmentList;


    public InfoCollege() {
        this.departmentList = new ArrayList<Department>();
        this.addDepartment("資訊安全專業");
        this.addDepartment("網絡安全專業");
        this.addDepartment("伺服器安全專業");
    }

    @Override
    public String getName() {
        return "資訊工程學院";
    }

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

    // 傳回一個資訊學院的系的疊代器
    @Override
    public Iterator createIterator() {
        return new InfoColleageIterator(departmentList);
    }

}

// 為了友善Client使用,提供一個OutPutImpl
class OutPutImpl {

    // 學院集合
    private List<College> collegeList;

    public OutPutImpl(List<College> collegeList) {

        this.collegeList = collegeList;
    }

    // 周遊所有學院, 然後調用printDepartment輸出各個學院的系
    public void printCollege() {

        // 從collegeList取出所有學院, Java中的List已經實作Iterator
        java.util.Iterator<College> javaIterator = (java.util.Iterator<College>) this.collegeList.iterator();

        while (javaIterator.hasNext()) {
            // 取出一個學院
            College college = javaIterator.next();
            System.out.println("======" + college.getName() + "======");
            // 得到學院對應疊代器,然後調用printDepartment進行列印
            this.printDepartment(college.createIterator());
        }
    }


    // 輸出學院的系
    private void printDepartment(Iterator iterator) {
        while (iterator.hasNext()) {
            Department department = (Department) iterator.next();
            // 數組中擷取到的department可能為null
            if (department != null) {
                System.out.println(department.getName());
            }
        }
    }

}
           

運作程式,結果如下:

======計算機學院======
大資料專業
Java專業
前端專業
======資訊工程學院======
資訊安全專業
網絡安全專業
伺服器安全專業