迭代器模式又稱游標模式,屬于行為型模式;指提供一些方法來順序訪問聚合物件中的一系列資料,而不暴露聚合物件的內部表象,迭代器模式是通過將聚合物件的遍歷行為分離出來,抽象成迭代器類來實作的,其目的是在不暴露聚合物件的內部結構的情況下,讓外部代碼透明地訪問聚合的內部資料,
迭代器模式是最常見的幾個設計模式之一,也是被廣泛地應用到Java語言API中的幾個設計模式之一,在Java語言的集合(Collection)框架中,廣泛使用迭代器來遍歷聚集的元素,
迭代器模式的UML類圖如下:

從上圖可知,迭代器模式涉及到抽象聚合角色、具體聚合角色、抽象迭代器角色、具體迭代器角色等四種角色:
- 抽象聚合(Aggregate)角色:定義存盤、添加、洗掉聚合物件以及創建迭代器物件的介面,
- 具體聚合(ConcreteAggregate)角色:實作抽象聚合類,回傳一個具體迭代器的實體,
- 抽象迭代器(Iterator)角色:定義訪問和遍歷聚合元素的介面,通常包含 hasNext()、first()、next() 等方法,
- 具體迭代器(Concretelterator)角色:實作抽象迭代器介面中所定義的方法,完成對聚合物件的遍歷,記錄遍歷的當前位置,
迭代器分為主動迭代和被動迭代,主要是相對于客戶端而言的,如果客戶端控制迭代的行程,那么這樣的迭代就是主動迭代,相反就是被動迭代,使用主動迭代的客戶端會明顯呼叫迭代器的next()等迭代方法,在遍歷的程序中向前迭代,而客戶端在使用被動迭代時,明顯不會呼叫迭代方法,而是由迭代器自行推進遍歷程序,而我們在開發程序中大部分都是使用的主動迭代,
學校院系例子
在一個大學里,由很多個學院組成,每個學院下又有很多系,如果要知道這個大學由多少個學院,一個學院由多少個專業,就可以使用迭代器模式,
該系統的UML類圖如下:

抽象聚合角色:
package com.charon.iterator;
import java.util.Iterator;
/**
* @className: College
* @description: 學院
* @author: charon
* @create: 2022-03-27 14:52
*/
public interface College {
/**
* 獲取學院的名稱
* @return
*/
String getName();
/**
* 添加學院
* @param name 名稱
* @param desc 描述
*/
void addDepartment(String name,String desc);
/**
* 回傳一個迭代器物件,用于遍歷
* @return
*/
Iterator createIterator();
}
具體聚合角色:
package com.charon.iterator;
import java.util.Iterator;
/**
* @className: ComputerCollege
* @description: 計算機學院
* @author: charon
* @create: 2022-03-27 14:56
*/
public class ComputerCollege implements College{
Department[] departments;
/**
* 下面系的個數
*/
int departmentNum;
public ComputerCollege() {
departments = new Department[3];
addDepartment("計算機科學與技術","計算機科學與技術");
addDepartment("電子科學與技術","電子科學與技術");
addDepartment("資訊與通信工程","資訊與通信工程");
}
@Override
public String getName() {
return "計算機學院";
}
@Override
public void addDepartment(String name, String desc) {
Department department = new Department(name, desc);
departments[departmentNum] = department;
departmentNum++;
}
@Override
public Iterator createIterator() {
return new ComputerCollegeIterator(departments);
}
}
package com.charon.iterator;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* @className: InfoCollege
* @description: 資訊工程學院
* @author: charon
* @create: 2022-03-27 15:11
*/
public class InfoCollege implements College{
List<Department> departments;
public InfoCollege() {
departments = new ArrayList<>(5);
addDepartment("電氣工程及自動化","電氣工程及自動化");
addDepartment("電子資訊工程","電子資訊工程");
addDepartment("測控技術與儀器","測控技術與儀器");
addDepartment("電子科學與技術","電子科學與技術");
addDepartment("物聯網工程","物聯網工程");
addDepartment("通信工程","通信工程");
}
@Override
public String getName() {
return "資訊工程學院";
}
@Override
public void addDepartment(String name, String desc) {
Department department = new Department(name, desc);
departments.add(department);
}
@Override
public Iterator createIterator() {
return new InfoCollegeIterator(departments);
}
}
具體迭代器角色:
package com.charon.iterator;
import java.util.Iterator;
/**
* @className: ComputerCollegeIterator
* @description:
* @author: charon
* @create: 2022-03-27 15:05
*/
public class ComputerCollegeIterator implements Iterator {
/**
* 存放專業的容器
*/
Department[] departments;
/**
* 游標,用于記錄遍歷的位置
*/
int cursor;
public ComputerCollegeIterator(Department[] departments) {
this.departments = departments;
}
@Override
public boolean hasNext() {
return cursor < departments.length && departments[cursor] != null;
}
@Override
public Object next() {
Department department = departments[cursor];
cursor++;
return department;
}
}
package com.charon.iterator;
import java.util.Iterator;
import java.util.List;
/**
* @className: InfoCollegeIterator
* @description:
* @author: charon
* @create: 2022-03-27 15:16
*/
public class InfoCollegeIterator implements Iterator {
List<Department> departments;
/**
* 陣列下標
*/
int index;
public InfoCollegeIterator(List<Department> departments) {
this.departments = departments;
}
@Override
public boolean hasNext() {
if (index >= departments.size() -1){
return false;
}
index++;
return true;
}
@Override
public Object next() {
return departments.get(index);
}
}
其他:
package com.charon.iterator;
/**
* @className: Department
* @description: 系
* @author: charon
* @create: 2022-03-27 14:58
*/
public class Department {
private String name;
private String desc;
public Department(String name, String desc) {
this.name = name;
this.desc = desc;
}
/**
* Gets the value of name
*
* @return the value of name
*/
public String getName() {
return name;
}
}
package com.charon.iterator;
import java.util.Iterator;
import java.util.List;
/**
* @className: OutputImpl
* @description:
* @author: charon
* @create: 2022-03-27 15:19
*/
public class OutputImpl {
List<College> colleges;
public OutputImpl(List<College> colleges) {
this.colleges = colleges;
}
/**
* 遍歷所有的學院,并依次輸出
*/
public void printCollege(){
Iterator<College> iterator = colleges.iterator();
while (iterator.hasNext()){
// 取出一個學院
College college = iterator.next();
System.out.println("學院:" + college.getName());
printDepartment(college.createIterator());
}
}
/**
* 輸出專業
* @param iterator
*/
private void printDepartment(Iterator iterator) {
while (iterator.hasNext()){
Department department = (Department) iterator.next();
System.out.println("該學院下的專業有:" + department.getName());
}
}
}
測驗:
package com.charon.iterator;
import java.util.ArrayList;
import java.util.List;
/**
* @className: Client
* @description:
* @author: charon
* @create: 2022-03-27 15:27
*/
public class Client {
public static void main(String[] args) {
// 創建學院
List<College> colleges = new ArrayList<>(2);
colleges.add(new ComputerCollege());
colleges.add(new InfoCollege());
OutputImpl output = new OutputImpl(colleges);
output.printCollege();
}
}
列印:
學院:計算機學院
該學院下的專業有:計算機科學與技術
該學院下的專業有:電子科學與技術
該學院下的專業有:資訊與通信工程
學院:資訊工程學院
該學院下的專業有:電子資訊工程
該學院下的專業有:測控技術與儀器
該學院下的專業有:電子科學與技術
該學院下的專業有:物聯網工程
該學院下的專業有:通信工程
迭代器模式的優點如下:
- 訪問一個聚合物件的內容而無須暴露它的內部表示,
- 遍歷任務交由迭代器完成,這簡化了聚合類,
- 它支持以不同方式遍歷一個聚合,甚至可以自定義迭代器的子類以支持新的遍歷,
- 增加新的聚合類和迭代器類都很方便,無須修改原有代碼,
- 封裝性良好,為遍歷不同的聚合結構提供一個統一的介面,
迭代器模式的缺點如下:
- 增加了類的個數,這在一定程度上增加了系統的復雜性
迭代器模式的應用場景
由于聚合與迭代器的關系非常密切,所以大多數語言在實作聚合類時都提供了迭代器類,因此大數情況下使用語言中已有的聚合類的迭代器就已經夠了,
迭代器模式通常在以下幾種情況使用,
- 當需要為聚合物件提供多種遍歷方式時,
- 當需要為遍歷不同的聚合結構提供一個統一的介面時,
- 當訪問一個聚合物件的內容而無須暴露其內部細節的表示時,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/450414.html
標籤:設計模式
上一篇:smtplib.SMTP.send_message將文本內容中的“發件人”替換為“發件人”
下一篇:設計模式之訪問者模式
