前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >设计模式-迭代子模式

设计模式-迭代子模式

作者头像
breezedancer
发布2018-09-12 15:43:19
3880
发布2018-09-12 15:43:19
举报
文章被收录于专栏:技术与生活技术与生活

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

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

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

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

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

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

代码语言:javascript
复制
public abstract class Aggregate {    public abstract MyIterator iterator();    public abstract Object getElement(int index);    public abstract int size();
}

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

代码语言:javascript
复制
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;
    }

}

抽象迭代子

代码语言:javascript
复制
public interface MyIterator {    //移动到第一个对象
    public void first();    //是否最后
    public boolean isLast();    //移动下一个
    public void next();    //当前对象
    public Object current();
}

一个具体的实现

代码语言:javascript
复制
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);
    }

}

来个客户端运行下看看

代码语言:javascript
复制
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 的,这个需要显示的强制转换。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2016-11-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 技术与生活 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档