Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> 《Android源碼設計模式解析與實戰》讀書筆記(十四)

《Android源碼設計模式解析與實戰》讀書筆記(十四)

編輯:關於android開發

《Android源碼設計模式解析與實戰》讀書筆記(十四)


第十四章、迭代器模式

迭代器模式,又叫做游標模式,是行為型設計模式之一。我們知道對容器對象的訪問必然會涉及遍歷算法,我們可以將遍歷的方法封裝在容器中,或者不提供遍歷方法,讓使用容器的人自己去實現去吧。這兩種情況好像都能夠解決問題。

然而在前一種情況,容器承受了過多的功能,它不僅要負責自己“容器”內的元素維護(添加、刪除等等),而且還要提供遍歷自身的接口;而且由於遍歷狀態保存的問題,不能對同一個容器對象同時進行多個遍歷。第二種方式倒是省事,卻又將容器的內部細節暴露無遺。

正因於此,迭代器模式應運而生,在客戶訪問類與容器體之間插入一個第三者–迭代器,很好的解決了上述弊端。

1.定義

提供一種方法順序訪問一個容器對象中的各個元素,而又不需要暴露該對象的內部表示。

2.使用場景

遍歷一個容器對象時。

3.簡單實現

用書中的例子:小民和小輝分別在公司兩個事業部,某天老板安排任務讓他們倆統計一下各自部門的員工數據。

員工實體類:

public class Employee {

    private String name;// 姓名
    private int age;// 年齡
    private String sex;// 性別
    private String position;// 職位

    public Employee(String name, int age, String sex, String position) {
        super();
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.position = position;
    }

    // 簡化代碼,省略setter和getter方法

    @Override
    public String toString() {
        return "Employee{" + "name='" + name + '\'' + ", age=" + age + ", sex="
                + sex + ", position='" + position + '\'' + "}";
    }
}

小輝部門:

public class CompanyHui {

private Employee[] array = new Employee[3];

    public CompanyHui(){
        array[0] = new Employee("輝哥", 28, "男", "程序猿");
        array[1] = new Employee("小紅", 23, "男", "程序猿");
        array[2] = new Employee("小輝", 25, "男", "程序猿");
    }

    public Employee[] getEmployees(){
        return array;
    }
}

小民部門:

public class CompanyMin {

    private List list = new ArrayList<>();

    public CompanyMin(){
        list.add(new Employee("小民", 26, "男", "程序猿"));
        list.add(new Employee("小芸", 22, "女", "測試"));
        list.add(new Employee("小方", 18, "女", "測試"));
        list.add(new Employee("可兒", 21, "女", "設計"));
        list.add(new Employee("朗情", 19, "女", "設計")); //吐槽一下,為什麼就小民一個男的,小輝部門全男的。
    }

    public List getEmployees(){
        return list;
    }
}

Boss查看:

public class Boss {
    public static void main(String[] args) {
        CompanyHui hui = new CompanyHui();
        Employee[] huiList = hui.getEmployees();
        for(int i = 0; i < huiList.length; i++){
            System.out.println(huiList[i]);
        }

        CompanyMin min = new CompanyMin();
        List minList = min.getEmployees();
        for(int i = 0; i < minList.size(); i++){
            System.out.println(minList.get(i).toString());
        }
    }
}

結果:

Employee{name='輝哥', age=28, sex=男, position='程序猿'}
Employee{name='小紅', age=23, sex=男, position='程序猿'}
Employee{name='小輝', age=25, sex=男, position='程序猿'}
Employee{name='小民', age=26, sex=男, position='程序猿'}
Employee{name='小芸', age=22, sex=女, position='測試'}
Employee{name='小方', age=18, sex=女, position='測試'}
Employee{name='可兒', age=21, sex=女, position='設計'}
Employee{name='朗情', age=19, sex=女, position='設計'}

這樣看似也沒有問題,但是如果有多個部門,每個部門有各自的實現,那麼我們就要在Boss類中增加一遍遍歷邏輯,這樣Boss類的功能會越來越多,同時暴露了內部細節。那麼我們需要定義一個迭代器接口:

public interface Iterator {

    /**
     * 是否還有下一個元素 
     * 
     * @return true表示有,false表示沒有
     */
    boolean hasNext();

    /**
     * 返回當前元素,並將位置移至下一位
     */
    Object next();
}

小民的迭代器:

public class MinIterator implements Iterator{

    private List list;
    private int position;

    public MinIterator(List list){
        this.list = list;
    }


    @Override
    public boolean hasNext() {
        return !(position > list.size() - 1 || list.get(position) == null);
    }

    @Override
    public Object next() {
        Employee e = list.get(position);
        position++;
        return e;
    }

}

小輝的迭代器:

public class HuiIterator implements Iterator{

    private Employee[] array;
    private int position;

    public HuiIterator(Employee[] array){
        this.array = array;
    }

    @Override
    public boolean hasNext() {
        return !(position > array.length - 1 || array[position] == null);
    }

    @Override
    public Object next() {
        Employee e = array[position];
        position++;
        return e;
    }

}

定義容器類的接口

public interface Company {

    /**
     * 返回一個迭代器對象
     * 
     * @return 迭代器對象
     */
    Iterator iterator();

}

修改一下之前的兩個容器類:

public class CompanyHui implements Company{

    private Employee[] array = new Employee[3];

    public CompanyHui(){
        array[0] = new Employee("輝哥", 28, "男", "程序猿");
        array[1] = new Employee("小紅", 23, "男", "程序猿");
        array[2] = new Employee("小輝", 25, "男", "程序猿");
    }

    public Employee[] getEmployees(){
        return array;
    }

    @Override
    public Iterator iterator() {
        return new HuiIterator(array);
    }
}
public class CompanyMin implements Company{

    private List list = new ArrayList<>();

    public CompanyMin(){
        list.add(new Employee("小民", 26, "男", "程序猿"));
        list.add(new Employee("小芸", 22, "女", "測試"));
        list.add(new Employee("小方", 18, "女", "測試"));
        list.add(new Employee("可兒", 21, "女", "設計"));
        list.add(new Employee("朗情", 19, "女", "設計"));
    }

    public List getEmployees(){
        return list;
    }

    @Override
    public Iterator iterator() {
        return new MinIterator(list);
    }
}

Boss查看:

public class Boss {
    public static void main(String[] args) {
        CompanyHui hui = new CompanyHui();
        check(hui.iterator());

        CompanyMin min = new CompanyMin();
        check(min.iterator());
    }

    private static void check(Iterator iterator){
        while (iterator.hasNext()) {
            System.out.println(iterator.next().toString());
        }
    }
}

結果不變,就不重復寫了。

4.Android源碼中的模式實現

1.Cursor

當我們使用SQLiteDatabase的query方法查詢數據庫時,會返回一個Cursor游標對象,該游標的實質就是一個具體的迭代器,我們可以使用它來遍歷數據庫查詢所得的結果集。

5.總結

迭代器模式發展至今,幾乎所有的高級語言都有相應的內置實現,對於開發者而言,已經極少會自己去實現迭代器了,所以本章內容更多的是了解而非應用。

1.優點

(1)符合面向對象設計原則中的單一職責原則。

(2)支持對容器對象的多種遍歷。弱化了容器類與遍歷算法之間的關系。

2.缺點

(1)類文件的增加。

(3)會出現ConcurrentModificationException異常。

(2)遍歷過程是一個單向且不可逆的遍歷。


  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved