什麼是迭代器模式
所謂迭代器模式,就是提供一種方法順序訪問一個容器對象的各個元素,而又不需要暴露該對象的內部表示的設計模式。
迭代器模式的實現方式
在客戶訪問類與容器體之間插入一個第三者——迭代器,就可以在不暴露該對象的內部表示的同時解決容器類承擔提供遍歷方法功能造成功能冗餘的問題。
《水滸傳》中“梁山泊全夥受招安”的時候,宋江給樑上好漢造了天罡地煞兩個花名冊(容器)。先定義一個容器接口:
public interface Company {
Iterator iterator();
} |
天罡容器:
public class SkyCompany implements Company {
private List<Bawcock> list = new ArrayList<>();
public SkyCompany() { list.add(new Bawcock("宋江","呼保義","天魁星","兵馬大元帥")); //此處省略34行代碼 list.add(new Bawcock("燕青","浪子","天巧星","步軍統領兼諜報隊長")); }
public List<Bawcock> getList(){ return list; }
@Override public Iterator iterator() { return new SkyIterator(list); } } |
地煞容器:
public class LandCompany implements Company {
private List<Bawcock> list = new ArrayList<>();
public LandCompany() { list.add(new Bawcock("朱武","神機軍師","地魁星","軍師參贊")); //此處省略70行代碼 list.add(new Bawcock("段景住","金毛犬","地狗星","機密情報營頭領")); }
public List<Bawcock> getList(){ return list; }
@Override public Iterator iterator() { return new LandIterator(list); } } |
天罡迭代器:
public class SkyIterator implements Iterator {
private List<Bawcock> bawcockList; private int position;
public SkyIterator(List<Bawcock> bawcockList) { this.bawcockList = bawcockList; }
@Override public boolean hasNext() { return !(position > bawcockList.size() - 1 || bawcockList.get(position) == null); }
@Override public Object next() { Bawcock bawcock = bawcockList.get(position); position++; return bawcock; } } |
地煞迭代器:
public class LandIterator implements Iterator {
private List<Bawcock> bawcockList; private int position;
public LandIterator(List<Bawcock> bawcockList) { this.bawcockList = bawcockList; }
@Override public boolean hasNext() { return !(position > bawcockList.size() - 1 || bawcockList.get(position) == null); }
@Override public Object next() { Bawcock bawcock = bawcockList.get(position); position++; return bawcock; } } |
好漢類:
public class Bawcock {
private String name;//姓名 private String nickname;//綽號 private String constellation;//星座 private String position;//職位
public Bawcock(String name, String nickname, String constellation, String position) { this.name = name; this.nickname = nickname; this.constellation = constellation; this.position = position; }
@Override public String toString() { return "Bawcock{" + "name='" + name + '\'' + ", nickname='" + nickname + '\'' + ", constellation='" + constellation + '\'' + ", position='" + position + '\'' + '}'; } } |
皇帝可以用迭代器檢閱梁山好漢的花名冊:
public static void check(Iterator iterator){ while(iterator.hasNext()){ Log.e("皇帝翻閱花名冊",iterator.next().toString()); } } |
但是如果皇帝想要修改梁山好漢的職位的時候:“令宋江等分開軍馬,各歸原所”,就會得到這個的答覆:“俺等衆頭領,生死相隨,誓不相舍!端的要如此,我們只得再回梁山泊去”。儘管道君皇帝宋徽宗碰了一鼻子灰,但我們明白了迭代器模式如何保證數據的安全。
Android源碼中的迭代器模式
(1)List和Map
迭代器模式一般不會交給開發者實現,Java的常見數據結構List和Map等都自帶迭代器。
(2)SQLiteDatabase
當我們使用SQLiteDatabase的query方法查詢數據庫時,會返回一個Cursor遊標對象,這就是一個迭代器。
Android開發中如何利用迭代器模式
迭代器模式的優點很明顯:支持以不同的方法去遍歷一個容器對象,也可以有多個遍歷,弱化了容器類與遍歷算法之間的關係。在遍歷一個容器對象時迭代器模式作用非常明顯,比如自定義一個支持多選的圖片選擇器。
需要注意的幾個問題
(1)迭代器模式在Java語言中具有相應的內置實現,極少數情況才需要開發者自己實現迭代器。
(2)迭代器模式增加類文件,造成代碼臃腫。