1 看一個具體的需求
編寫程式展示一個學校院系結構:需求是這樣,要在一個頁面中展示出學校的院系組成,一個學校有多個學院, 一個學院有多個系。如圖:
2 傳統的設計方案(類圖)
3 傳統的方式的問題分析
1) 將學院看做是學校的子類,系是學院的子類,這樣實際上是站在組織大小來進行分層次的
2) 實際上我們的要求是 :在一個頁面中展示出學校的院系組成,一個學校有多個學院,一個學院有多個系, 因此這種方案,不能很好實現的遍歷的操作
3) 解決方案:=> 迭代器模式
4 迭代器模式基本介紹
基本介紹
1) 迭代器模式(Iterator Pattern)是常用的設計模式,屬於行為型模式
2) 如果我們的集合元素是用不同的方式實現的,有陣列,還有 java 的集合類,或者還有其他方式,當客戶端要遍歷這些集合元素的時候就要使用多種遍歷方式,而且還會暴露元素的內部結構,可以考慮使用迭代器模式解決。
3) 迭代器模式,提供一種遍歷集合元素的統一介面,用一致的方法遍歷集合元素,不需要知道集合物件的底層表示,即:不暴露其內部的結構。
5 迭代器模式的原理類圖
- 對原理類圖的說明-即(迭代器模式的角色及職責)
1) Iterator : 迭代器介面,是系統提供,含義 hasNext, next, remove
2) ConcreteIterator : 具體的迭代器類,管理迭代
3) Aggregate :一個統一的聚合介面, 將客戶端和具體聚合解耦
4) ConcreteAggreage : 具體的聚合持有物件集合, 並提供一個方法,返回一個迭代器, 該迭代器可以正確遍歷集合
5) Client :客戶端, 通過 Iterator 和 Aggregate 依賴子類
6 迭代器模式應用例項
1) 應用例項要求
編寫程式展示一個學校院系結構:需求是這樣,要在一個頁面中展示出學校的院系組成,一個學校有多個學院, 一個學院有多個系。
2) 設計思路分析
3)程式碼實現
package com.lin.iterator; public class Department { private String name; private String desc; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } public Department(String name, String desc) { super(); this.name = name; this.desc = desc; } }
package com.lin.iterator; import java.util.Iterator; public interface College { String getName(); void addDepartment(String name, String desc); Iterator createIterator(); }
package com.lin.iterator; import java.util.Iterator; public class ComputerCollegeIterator implements Iterator{ // 這裡我們需要Department是以怎樣的方式存放 Department[] departments; int positon = 0; public ComputerCollegeIterator(Department[] departments) { this.departments = departments; } @Override public boolean hasNext() { if(positon >= departments.length || departments[positon] == null) { return false; } else{ return true; } } @Override public Object next() { Department department = departments[positon]; positon += 1; return department; } public void remove() { } }
package com.lin.iterator; import java.util.Iterator; public class ComputerCollege implements College { Department[] departments; int numOfDepartment = 0; // 儲存當前陣列的物件個數 public ComputerCollege() { departments = new Department[5]; addDepartment("Java專業", "Java專業"); addDepartment("前端", "前端"); addDepartment("大資料專業", "大資料專業"); } @Override public String getName() { return "計算機學院"; } @Override public void addDepartment(String name, String desc) { Department department = new Department(name, desc); departments[numOfDepartment] = department; numOfDepartment ++; } @Override public Iterator createIterator() { return new ComputerCollegeIterator(departments); } }
package com.lin.iterator; import java.util.Iterator; import java.util.List; public class InfoCollegeIteration implements Iterator { List<Department> departmentList; int index = -1; public InfoCollegeIteration(List<Department> departmentList) { super(); this.departmentList = departmentList; } @Override public boolean hasNext() { if(index >= departmentList.size() -1) { return false; } else { index ++; return true; } } @Override public Object next() { return departmentList.get(index); } public void remove() { } }
package com.lin.iterator; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class InfoCollege implements College { List<Department> departmentList; public InfoCollege() { departmentList = new ArrayList<Department>(); 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 InfoCollegeIteration(departmentList); } }
package com.lin.iterator; import java.util.Iterator; import java.util.List; public class OutPutImpl { // 學院集合 List<College> collegeList; public OutPutImpl(List<College> collegeList) { this.collegeList = collegeList; } // 輸出個學院的系 public void printCollege() { Iterator<College> iterator = collegeList.iterator(); while(iterator.hasNext()) { College college = iterator.next(); System.out.println("==========="+college.getName()+"==========="); printDepartment(college.createIterator()); } } // 輸出 學院輸出系 public void printDepartment(Iterator iterator) { while(iterator.hasNext()) { Department d = (Department)iterator.next(); System.out.println(d.getName()); } } }
package com.lin.iterator; import java.util.ArrayList; import java.util.List; public class Client { public static void main(String[] args) { List<College> collegeList = new ArrayList<College>(); ComputerCollege computerCollege = new ComputerCollege(); InfoCollege infoCollege = new InfoCollege(); collegeList.add(computerCollege); collegeList.add(infoCollege); OutPutImpl outPutImpl = new OutPutImpl(collegeList); outPutImpl.printCollege(); } }
7 迭代器模式在 JDK-ArrayList 集合應用的原始碼分析
1) JDK 的 ArrayList 集合中就使用了迭代器模式
2) 程式碼分析+類圖+說明
3) 對類圖的角色分析和說明
- 內部類 Itr 充當具體實現迭代器 Iterator 的類, 作為 ArrayList 內部類
- List 就是充當了聚合介面,含有一個 iterator() 方法,返回一個迭代器物件
- ArrayList 是實現聚合介面 List 的子類,實現了 iterator()
- Iterator 介面系統提供
- 迭代器模式解決了 不同集合(ArrayList ,LinkedList) 統一遍歷問題
8 迭代器模式的注意事項和細節
優點
- 1) 提供一個統一的方法遍歷物件,客戶不用再考慮聚合的型別,使用一種方法就可以遍歷物件了。
- 2) 隱藏了聚合的內部結構,客戶端要遍歷聚合的時候只能取到迭代器,而不會知道聚合的具體組成。
- 3) 提供了一種設計思想,就是一個類應該只有一個引起變化的原因(叫做單一責任原則)。在聚合類中,我們把迭代器分開,就是要把管理物件集合和遍歷物件集合的責任分開,
- 這樣一來集合改變的話,隻影響到聚合物件。而如果遍歷方式改變的話,隻影響到了迭代器。
- 4) 當要展示一組相似物件,或者遍歷一組相同物件時使用, 適合使用迭代器模式
缺點
- 每個聚合物件都要一個迭代器,會生成多個迭代器不好管理類
僅供參考,有錯誤還請指出!
有什麼想法,評論區留言,互相指教指教。