天天看點

疊代器模式

疊代器模式

Iterator Pattern

提供了一種方法順序通路一個聚合對象中的各個元素,而又無需暴露該對象的内部實作,這樣既可以做到不暴露集合的内部結構,又可讓外部代碼透明地通路集合内部的資料,疊代器模式屬于行為型模式。

描述

疊代器模式是針對集合對象而生的,對于集合對象而言,肯定會涉及到對集合的添加和删除操作,同時也肯定支援周遊集合元素的操作,我們此時可以把周遊操作放在集合對象中,但這樣的話,集合對象既承擔太多的責任了,面向對象設計原則中有一條就是單一職責原則,所有我們要盡可能地分離這些職責,用不同的類取承擔不同的責任,疊代器模式就是用疊代器類來承擔周遊集合的職責。

優點

  • 支援以不同的方式周遊一個聚合對象,并可以簡化聚合類。
  • 在同一個聚合上可以有多個周遊。
  • 在疊代器模式中,增加新的聚合類和疊代器類都很友善,無須修改原有代碼。
  • 疊代器模式使得通路一個聚合對象的内容而無需暴露它的内部表示,即疊代抽象。
  • 疊代器模式為周遊不同的集合結構提供了一個統一的接口,進而支援同樣的算法在不同的集合結構上進行操作。

缺點

  • 疊代器模式将存儲資料和周遊資料的職責分離,增加新的聚合類需要對應增加新的疊代器類,類的個數成對增加,這在一定程度上增加了系統的複雜性。
  • 疊代器模式在周遊的同時更改疊代器所在的集合結構可能會導緻出現異常,不能在周遊的同時更改集合中的元素數量。

适用環境

  • 通路一個聚合對象的内容而無須暴露它的内部表示。
  • 需要為聚合對象提供多種周遊方式。
  • 為周遊不同的聚合結構提供一個統一的接口。

實作

// 廣播電台示例

class RadioStation { // 電台
    constructor(frequency) {
        this.frequency = frequency;
    }
    
    getFrequency() {
        return this.frequency;
    }
}

class StationList { // 疊代器
    constructor(){
        this.index = -1;
        this.stations = [];
    }

    get(i){
        return this.stations[this.index];
    }

    hasNext(){
        let index = this.index + 1;
        return this.stations[index] !== void 0;
    }

    next(){
        return this.stations[++this.index];
    }

    addStation(station) {
        this.stations.push(station);
    }
    
    removeStation(toRemove) {
        const toRemoveFrequency = toRemove.getFrequency();
        this.stations = this.stations.filter(station => station.getFrequency() !== toRemoveFrequency);
    }
}

(function(){
    const stationList = new StationList();
    stationList.addStation(new RadioStation(89));
    stationList.addStation(new RadioStation(101));
    stationList.addStation(new RadioStation(102));
    stationList.addStation(new RadioStation(103.2));
    stationList.stations.forEach(station => console.log(station.getFrequency())); // 89 101 102 103.2
    stationList.removeStation(new RadioStation(89));
    while(stationList.hasNext()) console.log(stationList.next().getFrequency()); // 101 102 103.2
})();
           

每日一題

https://github.com/WindrunnerMax/EveryDay
           

參考

https://www.cnblogs.com/xuwendong/p/9898030.html
https://www.runoob.com/design-pattern/iterator-pattern.html
https://github.com/sohamkamani/javascript-design-patterns-for-humans#-iterator