一、概述 迭代器模式提供一種方法順序訪問一個聚合對象中的各個元素,而又不暴露其內部的表示。 二、解決問題 迭代器模式就是提供一種遍歷元素的統一介面,用一致的方法遍歷聚合元素。試想,如果我們的聚合元素是用不同的方式實現的,有些用了數組,有些用了java的集合類,或者還有其他方式,當客戶端要遍歷這些元素 ...
一、概述
迭代器模式提供一種方法順序訪問一個聚合對象中的各個元素,而又不暴露其內部的表示。
二、解決問題
迭代器模式就是提供一種遍歷元素的統一介面,用一致的方法遍歷聚合元素。試想,如果我們的聚合元素是用不同的方式實現的,有些用了數組,有些用了java的集合類,或者還有其他方式,當客戶端要遍歷這些元素的時候就要使用多種遍歷方式,而且還會暴露元素的內部結構。
三、應用實例
下麵我用一個在頁面展示一個學校院繫結構的例子來講解迭代器的用法,講完例子後我們再來看看迭代器的結構類圖。現在我們的需求是這樣,要在一個頁面中展示出學校的院系組成,它應該是樹狀結構的,一個學校有多個學院,一個學院有多個系。當然了,頁面的具體代碼就不寫了,我們就來分析後臺的實現方法。
前面學了面向介面編程,我們現在可以把學院抽象出來做成一個介面,設定裡面方法有getName,addDepartment(增加一個系),一個可以遍歷全部系的方法(暫且取名為CreateIterator,就是返回一個迭代器的方法)。看看介面的代碼實現
package com.jet.someinterface; import java.util.Iterator; /** * Created by Administrator on 2016/11/14. */ public interface College { public String getName(); /** * 增加一個系的方法 */ public void addDepartment(String name,String description); /** *返回一個迭代器用來遍歷每一個系 */ public Iterator createIterator(); }
學院下麵的是專業,我們把專業的對象創建出來
package com.jet.com.jet.vo; /** * Created by Administrator on 2016/11/14. * description:專業對象 */ public class DepartmentVo { private String name; private String description; public DepartmentVo(String name, String description) { this.name = name; this.description = description; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
創建第一學院對象(電腦學院),及其對應的迭代器
package com.jet.impl; import com.jet.com.jet.vo.DepartmentVo; import com.jet.someinterface.College; import java.util.Iterator; /** * Created by Administrator on 2016/11/14. * description:電腦學院 */ public class ComputerCollege implements College{ DepartmentVo[] departmentVos;//用來放置專業對象,註意這裡用的是數組 int numberOfDepartments = 0;//保存當前數組已有對象數 static final int MAX_DEPARTMENTS = 4;//控制專業數組大小 public String getName() { return "電腦學院"; } public ComputerCollege() { departmentVos = new DepartmentVo[MAX_DEPARTMENTS]; addDepartment("電腦科學與技術","電腦科學與技術"); addDepartment("軟體工程 ","軟體工程 "); addDepartment("網路工程","網路工程"); addDepartment("信息安全","信息安全"); } public void addDepartment(String name,String description) { if(numberOfDepartments >= MAX_DEPARTMENTS){ System.out.println("已超過學院最專業數限制,不能添加專業了!"); }else{ DepartmentVo departmentVo = new DepartmentVo(name,description); departmentVos[numberOfDepartments] = departmentVo; numberOfDepartments = numberOfDepartments + 1; } } public Iterator createIterator() { //返回一個遍歷器 return new ComputerCollegeIterator(departmentVos); } }
package com.jet.impl; import com.jet.com.jet.vo.DepartmentVo; import java.util.Iterator; /** * Created by Administrator on 2016/11/14. * decription:電腦學院的遍歷器,我們這裡是實現了java自帶的便利器Iterator */ public class ComputerCollegeIterator implements Iterator{ DepartmentVo[] departmentVos; int position = 0;//遍歷的位置 public ComputerCollegeIterator(DepartmentVo[] departmentVos) { this.departmentVos = departmentVos; } public boolean hasNext() { if(position >= departmentVos.length || departmentVos[position] == null ){ return false; }else{ return true; } } public Object next() { DepartmentVo departmentVo = departmentVos[position]; position = position + 1; return departmentVo; } //刪除的方法我們暫時不實現 public void remove() { } }
創建第二個學院(信息工程學院)及其迭代器
package com.jet.impl; import com.jet.com.jet.vo.DepartmentVo; import com.jet.someinterface.College; import java.util.ArrayList; import java.util.Iterator; import java.util.List; /** * Created by Administrator on 2016/11/14. * description:信息工程學院 */ public class InfoEngineeringCollege implements College{ List<DepartmentVo> departmentVoList;//註意這裡我們使用了集合來放置專業對象了 public String getName() { return "信息工程學院"; } public InfoEngineeringCollege() { this.departmentVoList = new ArrayList<DepartmentVo>(); addDepartment("電子信息工程","電子信息工程"); addDepartment("信息工程","信息工程"); addDepartment("通信工程","通信工程"); } public void addDepartment(String name, String description) { DepartmentVo departmentVo = new DepartmentVo(name,description); departmentVoList.add(departmentVo); } public Iterator createIterator() { return new InfoEngineeringCollengIterator(departmentVoList); } }
package com.jet.impl; import com.jet.com.jet.vo.DepartmentVo; import java.util.Iterator; import java.util.List; /** * Created by Administrator on 2016/11/14. * description:信息工程學院迭代器 */ public class InfoEngineeringCollengIterator implements Iterator{ int index = 0; List<DepartmentVo> departmentVoList; public InfoEngineeringCollengIterator(List<DepartmentVo> departmentVoList) { this.departmentVoList = departmentVoList; } public boolean hasNext() { if(index >= departmentVoList.size() ){ return false; }else { index = index + 1; return true; } } public Object next() { return departmentVoList.get(index); } public void remove() { } }
創建數據輸出類(也就是客戶端)
package com.jet.impl; import com.jet.com.jet.vo.DepartmentVo; import com.jet.someinterface.College; import java.util.Iterator; import java.util.List; /** * Created by Administrator on 2016/11/15. * description:模擬向頁面輸出院系信息的類,該類負責遍歷每個專業並列印其信息 */ public class OutputInfoImpl { //學院集合 List<College> collegeList; public OutputInfoImpl(List<College> collegeList) { this.collegeList = collegeList; } public void printDepartement(){ //java的集合實現了迭代器,可以直接調用方法取到 Iterator departmentIterator = collegeList.iterator(); while (departmentIterator.hasNext()){ College college = (College) departmentIterator.next(); System.out.println("--------" + college.getName() + "有以下專業-----------"); printDepartment(college.createIterator()); } } public void printDepartment(Iterator iterator){ while (iterator.hasNext()){ DepartmentVo departmentVo = (DepartmentVo) iterator.next(); System.out.println(departmentVo.getName()); } } }
測試迭代器
package com.jet.test; import com.jet.impl.ComputerCollege; import com.jet.impl.InfoEngineeringCollege; import com.jet.impl.OutputInfoImpl; import com.jet.someinterface.College; import java.util.ArrayList; import java.util.List; /** * Created by Administrator on 2016/11/15. * description:測試迭代器 */ public class IteratorTest { public static void main(String[] args) { //創建學院集合 List<College> collegeList = new ArrayList<College>(); College computerCollege = new ComputerCollege(); College infoEngineeringCollege = new InfoEngineeringCollege(); collegeList.add(computerCollege); collegeList.add(infoEngineeringCollege); OutputInfoImpl outputInfo = new OutputInfoImpl(collegeList); outputInfo.printDepartement(); } }
測試結果:
四、結構類圖
五、使用場景
當要展示一組相似對象,或者遍歷一組相同對象時使用。
六、優缺點
1、優點
(1)、提供一個統一的方法遍歷對象,客戶不用再考慮聚合的類型,使用一種方法就可以遍歷對象了。
(2)、隱藏了聚合的內部結構,客戶端要遍歷聚合的時候只能取到迭代器,而不會知道聚合的具體組成。
(3)、提供了一種設計思想,就是一個類應該只有一個引起變化的原因(叫做單一責任原則)。在聚合類中,我們把迭代器分開,就是要把管理對象集合和遍歷對象集合的責任分開,這樣一來集合改變的話,隻影響到聚合對象。而如果遍歷方式改變的話,隻影響到了迭代器。
2、缺點
每個聚合對象都要一個迭代器,會生成多個迭代器不好管理類。