设计模式-迭代子模式

迭代子模式可以顺序的访问集合内部的元素而不必知道集合内部表象。

多个对象聚集在一起形成集合的概念,所以集合对象也叫容器,包含 n 多对象的池子一样。集合对象需要提供一些方法,使得可以顺序访问内部对象。集合对象常见的问题分为两类,一是把一种集合对象转换为另外一个集合对象,由于集合对象各自的遍历集合不同,这里就需要修改客户端代码了(违背开闭原则);二是集合本身不变,迭代方法改变,这个时候需要修改集合对象。这两个问题都涉及到需要修改代码,也就违背了开闭原则(能够在不修改代码的情况下对功能进行扩展,开闭原则其实是需要把不变的与易变的进行分割)。针对这样的问题,在客户端和集合对象之间增加一个迭代子这么一个中间层,使得客户端和集合对象之间由直接变成间接,降低耦合力度。

迭代子模式的类图大概如下所示


Aggregate集合:创建迭代子的接口;
ConcreteAggregate 具体集合:实现迭代子接口;
Iterator 迭代子接口:给出迭代每个元素的接口;
ConcreteIterator 具体迭代子:实现迭代方法。

如果一个集合对象对外提供了修改内部元素的方法,那么这个接口就叫宽接口;如果不对外提供修改元素的方法,就叫窄接口,其实这叫法我觉得无所谓,关键是集合类对外提供修改接口,就破坏了集合对象的封装,而此时的迭代子在外部控制元素的迭代,作用相当于一个游标,有个雅称叫游标迭代子;改良的做法是集合对象对外不提供对元素的修改方法,只对迭代子提供宽接口。

下面使用代码更加形象的说明之。
集合类提供几个方法,第一个是获取迭代子;第二个是获得指定位置的元素了第三是获取集合元素的数量;

public abstract class Aggregate {

    public abstract MyIterator iterator();
    
    public abstract Object getElement(int index);
    
    public abstract int size();
}

具体集合类的实现,这里使用一个数组作为静态的内部元素,如果使用动态外部的元素需要改造

public class ConcreteAggregate extends Aggregate{

    private String[]arr={"A","B","C"};
    
    @Override
    public MyIterator iterator() {
        return new ConcreteIterator(this);
    }
    
    public Object getElement(int index){
        return arr[index];
    }
    
    public int size(){
        return arr.length;
    }

}

抽象迭代子

public interface MyIterator {
    //移动到第一个对象
    public void first();
    //是否最后
    public boolean isLast();
    //移动下一个
    public void next();
    //当前对象
    public Object current();
}

一个具体的实现

public class ConcreteIterator implements MyIterator{

    Aggregate agg;
    int size=0;
    int index=0;
    
    public ConcreteIterator(Aggregate agg) {
        this.agg=agg;
        size=agg.size();
    }
    
    @Override
    public void first() {
        index=0;
        
    }

    @Override
    public boolean isLast() {
        return index>=size;
    }

    @Override
    public void next() {
        if(index<size){
            index++;
        }
        
    }

    @Override
    public Object current() {
        return agg.getElement(index);
    }

}

来个客户端运行下看看

public class Client {

    public static void main(String[] args) {
        Aggregate agg=new ConcreteAggregate();
        MyIterator iterator = agg.iterator();
        //可以把 isLast 和 next 方法整合到一起
        while(!iterator.isLast()){
            System.out.println(iterator.current());
            iterator.next();
        }
    }
}

可以打印出A、B、C,而且可以新增新的迭代子和新的集合类实现来进行不同的顺序输出。
迭代子模式的意义是使得客户端与迭代子任务分开,使二者各自完成自己的主要工作,在集合对象发生改变或者迭代方法发生变化的时候,有了这个迭代子缓冲地带,我们可以尽量只对迭代子部分进行修改。并不是说客户端自己不可以迭代,只是不够优雅。

迭代子把集合的循环迭代方法进行了处理,集合本身不需要迭代;集合本身可以包含不仅一个的迭代子,根据情况获取不同的迭代子,进行不同的迭代子处理;遍历算法包括迭代子内部,因此迭代子独立于集合。迭代子的缺点是对象总是 Object 的,这个需要显示的强制转换。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容