Java 設計模式 -- 迭代器模式

迭代器模式: 提供一種方法順序訪問一個聚合對象中的各個元素,而又不暴露其內部的表示。

比如說,現在我們有兩個聚合對象,一個是數組,一個是 ArrayList, 利用這兩個對象分別存儲文理科課程信息,像下面這樣。

public class LiberalLessons {

    public static final int MAX_LESSONS = 3;
    private int numberOfLessons = 0;
    private String[] lessons;

    public LiberalLessons() {
        lessons = new String[MAX_LESSONS];
        addLessons("Political");
        addLessons("Geography");
        addLessons("History");
    }

    private void addLessons(String lesson) {
        lessons[numberOfLessons] = lesson;
        numberOfLessons++;
    }

    public String[] getLessons() {
        return lessons;
    }
}

public class ScienceLessons {
    private ArrayList<String> lessons;

    public ScienceLessons() {
        lessons = new ArrayList<>();
        addLessons("Physical");
        addLessons("Chemical");
        addLessons("Biological");
    }

    private void addLessons(String lesson) {
        lessons.add(lesson);
    }

    public ArrayList getLessons() {
        return lessons;
    }
}

可見,以上我們將信息保存在了不同的聚合對象中,那么如果我們想要同時打印文理科的課程,該怎么辦呢?

public class PrintHelper {
    private LiberalLessons liberalLessons;
    private ScienceLessons scienceLessons;

    public PrintHelper(LiberalLessons liberalLessons, ScienceLessons scienceLessons) {
        this.liberalLessons = liberalLessons;
        this.scienceLessons = scienceLessons;
    }

    public void print() {
        printLiberalLessons();
        printScienceLessons();
    }

    private void printLiberalLessons() {
        String[] lessons = liberalLessons.getLessons();
        System.out.println("Liberal Lessons : ");
        for (int i = 0; i < LiberalLessons.MAX_LESSONS; i++) {
            System.out.print(lessons[i] + "\t");
        }
        System.out.println();
    }

    private void printScienceLessons() {
        ArrayList<String> lessons = scienceLessons.getLessons();
        System.out.println("Science Lessons : ");
        for (int i = 0; i < lessons.size(); i++) {
            System.out.print(lessons.get(i) + "\t");
        }
        System.out.println();
    }
}

public class Client {
    public static void main(String[] args) {
        LiberalLessons liberalLessons = new LiberalLessons();
        ScienceLessons scienceLessons = new ScienceLessons();

        PrintHelper printHelper = new PrintHelper(liberalLessons, scienceLessons);
        printHelper.print();
    }
}

可見,在這里我又多寫了一個輔助類 PrintHelper, 這樣可以減少主函數中的代碼量,我個人不太喜歡在主函數寫太多的代碼。

來看看,由于我們使用了不同的聚合對象,導致我們不得不區別對待,如果有一種方法,能夠讓我們不管是針對哪種聚合對象都可以進行相同的操作就好了,這正是迭代器應該做的工作。

首先,我們看看 java.util.Iterator 接口

public interface Iterator<E> {
    boolean hasNext();
    E next();
    void remove();
}

hasNext() 方法返回一個布爾值,讓我們知道是否還有更多的元素。
next() 方法返回下一個元素的值。
remove() 用于刪除由 next() 方法返回的最后一項。

下面我們就利用Iterator 對以上代碼進行改寫。

public class LiberalIterator implements Iterator<String> {

    private String[] lessons;
    private int position = 0;

    public LiberalIterator(String[] lessons) {
        this.lessons = lessons;
    }

    @Override
    public boolean hasNext() {
        if (position >= lessons.length) {
            return false;
        }
        return true;
    }

    @Override
    public String next() {
        String lesson = lessons[position];
        position += 1;
        return lesson;
    }

    @Override
    public void remove() {
        throw new UnsupportedOperationException("You can not remove element !");
    }
}

我們針對文科課程類寫了一個迭代器,在 remove() 方法中我們拋出了一個異常,表示我們不希望客戶端通過迭代器刪除元素。實際上我們也只需要寫這么一個迭代器類,因為在 ScienceLessons 類中我們使用的是 ArrayList ,它是自帶 Iterator 的,我們只需要調用 iterator() 方法即可。

接下來,我們就將 LiberalLessonsScienceLessons 中的 getLessons() 方法進行改寫,寫成 createIterator() 方法。

public Iterator<String> createIterator() {
    return new LiberalIterator(lessons);
}
public Iterator<String> createIterator() {
    return lessons.iterator();
}

現在再看看我們的 PrintHelper 該怎么書寫代碼。

public class PrintHelper {
    private LiberalLessons liberalLessons;
    private ScienceLessons scienceLessons;

    public PrintHelper(LiberalLessons liberalLessons, ScienceLessons scienceLessons) {
        this.liberalLessons = liberalLessons;
        this.scienceLessons = scienceLessons;
    }

    public void print() {
        System.out.println("Liberal Lessons : ");
        Iterator<String> liberalIterator = liberalLessons.createIterator();
        print(liberalIterator);
        System.out.println();

        System.out.println("Science Lessons : ");
        Iterator<String> scienceIterator = scienceLessons.createIterator();
        print(scienceIterator);
        System.out.println();


    }

    private void print(Iterator<String> iterator) {
        while (iterator.hasNext()) {
            System.out.print(iterator.next() + "\t");
        }
    }
}

這樣的話,我們就可以不必區分聚合對象,只需要根據類中提供的迭代器就可以訪問元素,而且這個時候我們也不知道類的內部用的是哪種聚合類型。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,362評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,577評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,486評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,852評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,600評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,944評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,944評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,108評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,652評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,385評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,616評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,111評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,798評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,205評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,537評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,334評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,570評論 2 379

推薦閱讀更多精彩內容