認識迭代器模式
在系統開發中,集合對象內部表示各不相同。底層構造也盡不相同。對於這些對象,我們希望在不暴露其底層和內部表示的同時,可以使外部客戶訪問其中元素。
迭代器模式就爲這一需求提供了極其優雅的實現,接下來就讓我們來認識認識迭代器模式:
迭代器模式,提供一種遍歷集合元素的統一接口,用一致的方法遍歷集合元素,不需要知道集合對象的底層表示,即:不暴露其內部的結構。
- 迭代器模式(Iterator Pattern)是常用的設計模式,屬於行爲型模式
- 如果我們的集合元素是用不同的方式實現的,有數組,還有 java 的集合類,或者還有其他方式,當客戶端要遍歷這些集合元素的時候就要使用多種遍歷方式,而且還會暴露元素的內部結構,可以考慮使用迭代器模式解決
模式的特點
迭代器(Iterator)模式的主要優點如下:
- 訪問一個聚合對象的內容而無須暴露它的內部表示。
- 遍歷任務交由迭代器完成,這簡化了聚合類。
- 它支持以不同方式遍歷一個聚合,甚至可以自定義迭代器的子類以支持新的遍歷。
- 增加新的聚合類和迭代器類都很方便,無須修改原有代碼。
- 封裝性良好,爲遍歷不同的聚合結構提供一個統一的接口。
其主要缺點是:增加了類的個數,這在一定程度上增加了系統的複雜性。
原理類圖與角色說明
角色說明
迭代器模式主要包含以下角色。
- 抽象聚合(Aggregate)角色:定義存儲、添加、刪除聚合對象以及創建迭代器對象的接口。
- 具體聚合(ConcreteAggregate)角色:實現抽象聚合類,返回一個具體迭代器的實例。
- 抽象迭代器(Iterator)角色:定義訪問和遍歷聚合元素的接口,通常包含 hasNext()、first()、next() 等方法。
- 具體迭代器(Concretelterator)角色:實現抽象迭代器接口中所定義的方法,完成對聚合對象的遍歷,記錄遍歷的當前位置。
應用實例
下面以遍歷輸出院系的不同底層存儲專業爲例,應用迭代器模式:
創建抽象聚合(Aggregate):學院類
public interface College {
public String getName();
//增加專業的方法
public void addDepartment(String name, String desc);
//返回一個迭代器,遍歷
public Iterator createIterator();
}
創建具體聚合(ConcreteAggregate):具體學院類
//計算機學院——以數組來存儲專業
public class ComputerCollege implements College {
Department[] departments;
int numOfDepartment = 0 ;// 保存當前數組的對象個數
public ComputerCollege() {
departments = new Department[5];
addDepartment("Java 專業", " Java 專業 ");
addDepartment("PHP 專業", " PHP 專業 ");
addDepartment("大數據專業", " 大數據專業 ");
}
@Override
public String getName() {
return "計算機學院";
}
@Override
public void addDepartment(String name, String desc) {
if (numOfDepartment < departments.length) {
Department department = new Department(name, desc);
departments[numOfDepartment] = department;
numOfDepartment += 1;
}
}
@Override
public Iterator createIterator() {
return new ComputerCollegeIterator(departments);
}
}
//信息工程學院——用list來存儲專業
public class InfoCollege implements College {
List<Department> departmentList;
public InfoCollege() {
departmentList = new LinkedList<>();
addDepartment("信息安全專業", " 信息安全專業 ");
addDepartment("網絡安全專業", " 網絡安全專業 ");
addDepartment("服務器安全專業", " 服務器安全專業 ");
}
@Override
public String getName() {
return "信息工程學院";
}
@Override
public void addDepartment(String name, String desc) {
Department department = new Department(name, desc);
departmentList.add(department);
}
@Override
public Iterator createIterator() {
return new InfoCollegeIterator(departmentList);
}
}
創建抽象迭代器(Iterator)
public interface Iterator {
Object first();
Object next();
boolean hasNext();
}
創建具體迭代器(Concretelterator)
//計算機學院迭代器
public class ComputerCollegeIterator implements Iterator {
//這裏 Department 是以數組的方式存放
Department[] departments;
int index = 0;//遍歷的位置
public ComputerCollegeIterator(Department[] departments) {
this.departments = departments;
}
@Override
public Object first() {
return departments[0];
}
@Override
public Object next() {
Department department = departments[index];
index ++;
return department;
}
//判斷數組中是否還有下一個元素
@Override
public boolean hasNext() {
if (index >= departments.length || departments[index] == null){
return false;
} else {
return true;
}
}
}
//信息工程學院迭代器
public class InfoCollegeIterator implements Iterator {
// 信息工程學院是以 List 方式存放專業
List<Department> departmentList;
int index = -1;//索引
public InfoCollegeIterator(List<Department> departmentList) {
this.departmentList = departmentList;
}
@Override
public Object first() {
return departmentList.get(0);
}
@Override
public Object next() {
return departmentList.get(index);
}
//判斷list中是否還有下一個元素
@Override
public boolean hasNext() {
if (index >= departmentList.size() - 1){
return false;
} else {
index ++;
return true;
}
}
}
客戶端調用測試
public class Client {
public static void main(String[] args) {
//創建 學院
College computerCollege = new ComputerCollege();
College infoCollege = new InfoCollege();
//創建 各個學院的迭代器
Iterator iterator = computerCollege.createIterator();
Iterator iterator1 = infoCollege.createIterator();
//輸出 計算機學院 下的院系
System.out.println("==========="+computerCollege.getName()+"===============");
printDepartment(iterator);
//輸出 信息工程學院 下的院系
System.out.println("==========="+infoCollege.getName()+"===============");
printDepartment(iterator1);
}
//輸出 學院輸出 系
public static void printDepartment(Iterator iterator) {
Department first = (Department) iterator.first();
System.out.println("第一個專業:" + first.getName());
while(iterator.hasNext()) {
Department d = (Department)iterator.next();
System.out.println(d.getName());
}
}
}
輸出結果:
===========計算機學院===============
第一個專業:Java 專業
Java 專業
PHP 專業
大數據專業
===========信息工程學院===============
第一個專業:信息安全專業
信息安全專業
網絡安全專業
服務器安全專業