zoukankan      html  css  js  c++  java
  • 大话设计模式笔记(十七)の迭代器模式

    迭代器模式

    定义

    提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。

    什么时候用?

    • 当你需要访问一个聚集对象,而且不管这些对象是什么都需要遍历的时候,你就应该考虑用迭代器模式
    • 你需要对聚集有多种方式遍历时,可以考虑用迭代器模式。

    UML图

    模板代码

    Aggregate

    /**
     * 聚集抽象类
     * Created by callmeDevil on 2019/8/17.
     */
    public abstract class Aggregate {
        // 创建迭代器
        public abstract Iterator createIterator();
    }
    

    Iterator

    /**
     * 迭代器抽象类
     * Created by callmeDevil on 2019/8/17.
     */
    public abstract class Iterator {
        // 用于定义得到开始对象、得到下一对象、判断是否到结尾、当前对象等抽象方法
        public abstract Object first();
        public abstract Object next();
        public abstract boolean isDone();
        public abstract Object currentItem();
    }
    

    ConcreteAggregate

    /**
     * 具体聚集类
     * Created by callmeDevil on 2019/8/17.
     */
    public class ConcreteAggregate extends Aggregate {
    
        // 存放聚合对象
        private List<Object> items = new ArrayList();
    
        @Override
        public Iterator createIterator() {
            return new ConcreteIterator(this);
        }
    
        // 返回聚集的总个数
        public int count() {
            return items.size();
        }
    
        // 声明一个索引器
        public Object get(int index) {
            return items.get(index);
        }
        public boolean set(Object o) {
            return items.add(o);
        }
    
    }
    

    ConcreteIterator

    /**
     * 具体迭代器类
     * Created by callmeDevil on 2019/8/17.
     */
    public class ConcreteIterator extends Iterator {
    
        // 定义一个具体聚集对象
        private ConcreteAggregate aggregate;
        private int current = 0;
    
        public ConcreteIterator(ConcreteAggregate aggregate){
            // 初始化时将具体的聚集对象传入
            this.aggregate = aggregate;
        }
    
        @Override
        public Object first() {
            // 得到聚集的第一个对象
            return aggregate.get(0);
        }
    
        @Override
        public Object next() {
            Object ret = null;
            current++;
            if (current < aggregate.count()) {
                // 得到聚集的下一个对象
                ret = aggregate.get(current);
            }
            return ret;
        }
    
        @Override
        public boolean isDone() {
            // 判断当前是否遍历到结尾
            return current >= aggregate.count();
        }
    
        @Override
        public Object currentItem() {
            // 返回当前的聚集对象
            return aggregate.get(current);
        }
    
    }
    

    测试

    public class Test {
        public static void main(String[] args) {
            // 公交车聚集对象
            ConcreteAggregate a = new ConcreteAggregate();
            // 新上来的乘客
            a.set("路飞");
            a.set("鸣人");
            a.set("一护");
            a.set("悟空");
            a.set("纳兹");
            a.set("琦玉");
            // 售票员登场,看好上车的是哪些人,即声明迭代器对象
            Iterator i = new ConcreteIterator(a);
            System.out.println(String.format("车位No.1乘客:%s", i.first()));
            while (!i.isDone()){
                System.out.println(String.format("%s 来不及解释了,快上车!", i.currentItem()));
                i.next();
            }
        }
    }
    

    测试结果

    车位No.1乘客:路飞
    路飞 来不及解释了,快上车!
    鸣人 来不及解释了,快上车!
    一护 来不及解释了,快上车!
    悟空 来不及解释了,快上车!
    纳兹 来不及解释了,快上车!
    琦玉 来不及解释了,快上车!
    

    倒序遍历

    ConcreteIteratorDesc

    /**
     * 倒序具体迭代器
     * Created by callmeDevil on 2019/8/17.
     */
    public class ConcreteIteratorDesc extends Iterator{
    
        // 定义一个具体聚集对象
        private ConcreteAggregate aggregate;
        private int current = 0;
    
        public ConcreteIteratorDesc(ConcreteAggregate aggregate){
            // 初始化时将具体的聚集对象传入
            this.aggregate = aggregate;
            current = aggregate.count() - 1;  //不同1
        }
    
        @Override
        public Object first() {
            // 得到聚集的第一个对象
            return aggregate.get(aggregate.count() - 1); //不同2
        }
    
        @Override
        public Object next() {
            Object ret = null;
            current--;  //不同3
            if (current >= 0) {  //不同4
                // 得到聚集的下一个对象
                ret = aggregate.get(current);
            }
            return ret;
        }
    
        @Override
        public boolean isDone() {
            // 判断当前是否遍历到结尾
            return current < 0;  //不同5
        }
    
        @Override
        public Object currentItem() {
            // 返回当前的聚集对象
            return aggregate.get(current);
        }
    
    }
    

    测试

    将顺序测试类中声明迭代器具体对象改为倒序的 ConcreteIteratorDesc 即可。

    测试结果

    车位No.1乘客:琦玉
    琦玉 来不及解释了,快上车!
    纳兹 来不及解释了,快上车!
    悟空 来不及解释了,快上车!
    一护 来不及解释了,快上车!
    鸣人 来不及解释了,快上车!
    路飞 来不及解释了,快上车!
    

    总结

    迭代器模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可以让外部代码透明的访问集合内部的数据。

  • 相关阅读:
    准备用协程模拟经典的生产者消费者
    重载操作符号
    对象池
    ssh加key
    oracle存储过程(PL/SQL)
    获取服务器ip地址
    【STL系列】结构体排序
    strtol sort snprintf snscanf strtok
    cxGrid动态创建带CheckBox列时遇到的问题...
    Windows2003 安装PostgreSQL9.0 UUID解决‘ERROR:无法载入程式库’问题
  • 原文地址:https://www.cnblogs.com/call-me-devil/p/11368582.html
Copyright © 2011-2022 走看看