设计模式_迭代子模式(19)

来源:互联网 发布:知乎手机端发表文章 编辑:程序博客网 时间:2024/06/03 17:24
  • 什么是迭代子模式
  • 迭代子模式的例子
  • 迭代子模式的优缺点
  • 迭代子模式的使用场景
  • 闲言碎语

什么是迭代子模式

   不知道大家在学习Map的时候有没有遇到对map进行遍历的情况?刚开始接触的时候感觉他确实很好用.但经常未实现对它的遍历而苦恼.
   迭代子模式又叫游标(Cursor)模式,是对象的行为模式。迭代子模式可以顺序地访问一个聚集中的元素而不必暴露聚集的内部表象(internalrepresentation)。他们都分为以下几个角色: n● 抽象迭代子(Iterator)角色:此抽象角色定义出遍历元素所需的接口。
  ● 具体迭代子(ConcreteIterator)角色:此角色实现了Iterator接口,并保持迭代过程中的游标位置。
  ● 聚集(Aggregate)角色:此抽象角色给出创建迭代子(Iterator)对象的接口。
  ● 具体聚集(ConcreteAggregate)角色:实现了创建迭代子(Iterator)对象的接口,返回一个合适的具体迭代子实例。
  ● 客户端(Client)角色:持有对聚集及其迭代子对象的引用,调用迭代子对象的迭代接口,也有可能通过迭代子操作聚集元素的增加和删除。

迭代子模式的例子

抽象迭代子(Iterator)角色

package com.designPattern.aggregate;/** * 迭代子模式的接口 * * @author jason * * @param <T> */public interface Iterator<T> {    /**     * 得到对象的大小     *     * @return     */    public int getSize();    // 得到下一元素    public T getNext();    // 得到制定指定位置的元素    public T get(int i);    // 以下省略其他方法}



聚集角色:此抽象角色给出创建《迭代子》对象的接口

package com.designPattern.aggregate;/** * 聚集对象的接口 * * @author jason * * @param <T> */public interface Aggregate<T> {    public Iterator<String> createIterator();    // 得到制定指定位置的元素    public T get(int i);    // 以下省略其他方法}




具体迭代子对象
package com.designPattern.aggregate;/** * 具体的迭代子对象 * * @author Jason * */public class ConcreteIterator implements Iterator<String> {    private Aggregate<String> context;    private int location = 0;    private int size = 0;    public ConcreteIterator(ConcreteAggregate context) {        this.context = context;        size = context.getLength();    }    @Override // 获得长度的对象    public int getSize() {        return size;    }    @Override // 得到下一个元素    public String getNext() {        return get(location);    }    @Override // 得到指定元素    public String get(int i) {        if (i < size) {            return context.get(i);// 可以看出,实际很多东西还是需要底层提供方法接口才可以实现        }        return null;    }}




具体的聚集对象

package com.designPattern.aggregate;/** * 具体的聚集角色类 * * @author Jason * */public class ConcreteAggregate implements Aggregate<String> {    String value;    public ConcreteAggregate(String value) {        this.value = value;    }    @Override // 创建迭代子对象    public Iterator<String> createIterator() {        // TODO Auto-generated method stub        return new ConcreteIterator(this);    }    public int getLength() {        if (value == null) {            return 0;        } else {            return value.length();        }    }    @Override    public String get(int i) {        return String.valueOf(value.charAt(i));    }}

测试类

package com.designPattern.aggregate;import org.junit.Test;public class TestCase {    @Test    public void test() {        String test = "I`m jason";        Aggregate<String> aggregate = new ConcreteAggregate(test);        Iterator<String> iterator = aggregate.createIterator();        System.out.println(iterator.get(2));        System.out.println("字符的长度:" + iterator.getSize());    }}


迭代子模式的优点和缺点
 1、迭代子模式的优点:
  (1)迭代子模式简化了聚集的界面。迭代子具备了一个遍历接口,这样聚集的接口就不必具备遍历接口。
  (2)每一个聚集对象都可以有一个或一个以上的迭代子对象,每一个迭代子的迭代状态可以是彼此独立的。因此,一个聚集对象可以同时有几个迭代在进行之中。
  (3)由于遍历算法被封装在迭代子角色里面,因此迭代的算法可以独立于聚集角色变化。由于客户端拿到的是一个迭代子对象,因此,不必知道聚集对象的类型,就可以读取和遍历聚集对象。这样即便聚集对象的类型发生变化,也不会影响到客户端的遍历过程。
       

 2、迭代子模式的缺点:

  (1)迭代子模式给客户端一个聚集被顺序化的错觉,因为大多数的情况下聚集的元素并没有确定的顺序,但是迭代必须以一定线性顺序进行。如果客户端误以为顺序是聚集本身具有的特性而过度依赖于聚集元素的顺序,很可能得出错误的结果。
  (2)迭代子给出的聚集元素没有类型特征。一般而言,迭代子给出的元素都是Object类型,因此,客户端必须具备


迭代子模式的使用场景

   需要顺序访问集合内部的元素而不必知道集合内部表象的时候!

闲言碎语
   在java集合中大量用到了这种模式.这里只是简单的模拟出原理.有兴趣的可以去看java中set对其的实现.详细可以学到不少的知识!