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

    人物:大鸟,小菜

    事件:大鸟小菜去乘公交车,上车后看见售票员要求乘客进行买票,并发现售票员不管是谁,只要有对方一上车,就能准确记住并叫住他让他买票,而且不管对方什么身份,不管你是公司员工还是小偷,只要上车,就要买票,大鸟由此给小菜讲解了迭代器模式。


    迭代器模式:

    1.对迭代器进行简介

    2.通过迭代器实现公交车买票事件

    3.反向遍历,通过迭代器实现公交车买票事件

    迭代器模式简介

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

    2.用到的场景:

      (1)售票员不管是小偷还是公司员工,不管是中国人还是外国人,只要上车都要买票,也就是说当需要访问一个聚合对象,而且不管这些对象是什么都需要遍历的时候,就应该考虑迭代器模式

      (2)售票员可以从车头到车尾来售票,也可以从车尾到车头来售票,当需要对聚合对象进行多种方式遍历时,可以考虑用迭代器模式

    3.举例:迭代器模式是为了遍历不同的聚合对象,提供如开始,下一个,是否结束,当前哪一项等统一的接口,如很常见的for(;;)

    迭代器实现

    1.结构图:

    2.代码实现:

    Iterator类,迭代器抽象类:

    public abstract class Iterator {
        public abstract Object first();
    
        public abstract Object next();
    
        public abstract boolean isDone();
    
        public abstract Object currentItem();
    }

    Aggregate类,聚合抽象类:

    //用于创建迭代器
    public
    abstract class Aggregate { public abstract Iterator createIterator(); }

    ConcreteIterator类,具体迭代器类:

    @Data
    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.getItems().get(0); }
    //得到聚合的下一个对象 @Override
    public Object next() { Object ret = null; current++; if (current < aggregate.count()) { ret = aggregate.getItems().get(current); } return ret; } @Override public boolean isDone() { return current >= aggregate.count() ? true : false; }
    //返回当前的聚合对象 @Override
    public Object currentItem() { return aggregate.getItems().get(current); } }

    ConcreteAggregate类,具体聚合类,继承Aggregate

    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 List<Object> getItems() {
            return items;
        }
    
        public void setItems(List<Object> items) {
            this.items = items;
        }
    }

    客户端代码:

    @Slf4j
    public class IteratorClient {
        public static void main(String[] args) {
            ConcreteAggregate a = new ConcreteAggregate();
            List<Object> items = new ArrayList<>();
            Object a0 = "大鸟";
            Object a1 = "小菜";
            Object a2 = "行李";
            Object a3 = "老外";
    
            items.add(a0);
            items.add(a1);
            items.add(a2);
            items.add(a3);
            a.setItems(items);
    
            Iterator iterator = new ConcreteIterator(a);
            Object item = iterator.first();
            while (!iterator.isDone()) {
                log.info(iterator.currentItem() + "请买车票");
                iterator.next();
            }
        }
    }

    输出结果:

    大鸟请买车票
    小菜请买车票
    行李请买车票
    老外请买车票

    小菜:为什么非要用Iterator抽象类呢,好像直接使用也是可以的

    大鸟:那是因为你没有注意到迭代器的第二个好处 --> 当你需要对聚合对象进行多种方式遍历时,可以考虑用迭代器模式 

    小菜从后向前遍历版的迭代器实现

    ConcreteIteratorDesc类,实现一个从后向前的迭代器:

    public class ConcreteIteratorDesc extends Iterator {
        private ConcreteAggregate aggregate;
        private int current = 0;
    
        public ConcreteIteratorDesc(ConcreteAggregate aggregate) {
            this.aggregate = aggregate;
            current = aggregate.count() - 1;
        }
    
        @Override
        public Object first() {
            return aggregate.getItems().get(aggregate.count() - 1);
        }
    
        @Override
        public Object next() {
            Object ret = null;
            current--;
            if (current >= 0) {
                ret = aggregate.getItems().get(current);
            }
            return ret;
        }
    
        @Override
        public boolean isDone() {
            return current < 0 ? true : false;
        }
    
        @Override
        public Object currentItem() {
            return aggregate.getItems().get(current);
        }
    }

    客户端:

    //Iterator iterator = new ConcreteIterator(a);
    Iterator iterator = new ConcreteIteratorDesc(a);

    输出结果如下,与之前结果相反:

    老外请买车票
    行李请买车票
    小菜请买车票
    大鸟请买车票

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

  • 相关阅读:
    Qt与VC编程合作起龌龊
    谈谈误差补偿
    谈谈单片机编程入门方法
    小议设计模式
    创建VS工程使用神经网络库——FANN
    设计一个循环缓冲区模板
    旧文备份:FFTW介绍
    旧文备份:硬盘MBR引导记录损坏的一种修复方法
    How to disable the unused macros warning? --rust
    看阿里架构师是如何在高并发的情景下运筹帷幄
  • 原文地址:https://www.cnblogs.com/wencheng9012/p/13442047.html
Copyright © 2011-2022 走看看