设计模式——迭代器(Iterator)模式

  • 概述

  迭代器模式简单的说(按我目前的理解)就是一个类提供一个对外迭代的接口,方面调用者迭代。这个迭代接口至少包括两个方法:hasNext()--用于判断是否还有下一个,next()--用于取出下一个对象(或值)。而外部使用这个类(取出这个类中的对象或值)时,不用关心这个类存储对象或数据的具体数据结构,即使这个类的存储数据结构临时发生改变,调用者不作任何代码修改仍然可以正常工作。从而实现代码的可重用性和低耦合性。下面以实例说明。

  • 实例

  假设有两个书架(BookShelf),一个书架用数组Array的形式存放书,另一个书架用ArrayList的形式存放书,两个书架可以存放多本书(Book)的名字,Main方法通过书架取出书名打印出来。

  传统模式:很容易想到第一个书架通过一个方法返回存放书的数组,另一个书架返回存放书的ArrayList。就像下面这样:

//传统模式:
    public Book[] getBooks(){
        return  books;
    }
    //普通模式
    public ArrayList<Book> getBooks(){
        return  books;
    }

  这样的缺点是什么呢?缺点在于当我们同时获取到这两个书架时,迭代输出的方式就有所不同,因为一个是数组,一个是List,这个很容易想到吧,可能你觉得很简单,但是如果有十个,有几十个用不同的数据结构存储呢,迭代的方式又要改。并且,如果我开始用的数组存放书,后来我又不想用数组而改用List存放呢?那岂不是既要修改存放书的代码的同时又要修改迭代输出的代码?Oh,No..太麻烦了吧。可能你会想自己写的代码,干嘛每个书架存放书的数据结构要不同呢?那如果不是自己写的呢?比如我现在要合并多个餐馆的菜单为一个菜单并输出打印,而这些菜单的存储方式肯定不同,很有可能这几个餐馆的代码都不是同一个人写的。这时候我们再去一个一个循环未免也太麻烦。

  使用迭代器模式:既然我不同的书架存放书的数据结构不同,那我可以每个书架对外提供一个迭代接口,而每个接口都包含有hasNext方法和Next方法。这时在外部循环迭代输出时,就不用担心每个书架的书是怎样存放的,我只需要能通过Next方法取出书就可以了,就像下面这样:

数组存放:

public class BookShelf {

    private Book[] books;
    private int last = 0;

    public BookShelf(int maxsize) {
        this.books = new Book[maxsize];
    }

    public Book getBookAt(int index){
        return books[index];
    }

    public void appendBook(Book book){
        this.books[last] = book;
        last++;
    }

    public int getLength(){
        return  last;
    }

//    //传统模式:
//    public Book[] getBooks(){
//        return  books;
//    }

    public Iterator iterator() {
//        return new BookShelfIterator(this);
        return  new BookShelfIterator();
    }

    class  BookShelfIterator implements  Iterator{
//        private BookShelf bookShelf; //采用内部类,可以直接调用外部类方法,不用添加引用。
        private int index ;
        public BookShelfIterator() {
//            this.bookShelf=bookShelf;
            this.index = 0;
        }

        @Override
        public boolean hasNext() {
            if (index < getLength()){
                return  true;
            }else {
                return  false;
            }
        }
        @Override
        public Object next() {
            Book book  = getBookAt(index);
            index++;
            return book;
        }
    }
}

ArrayList存放:

import java.util.ArrayList;

public class BookShelf1 {

    private ArrayList<Book> books ;//使用ArrayList实现

    public BookShelf1(int maxsize) {
        this.books = new ArrayList<>(maxsize);//初始大小
    }

    public Book getBookAt(int index){
        return  books.get(index);
    }

    public void appendBook(Book book){
        this.books.add(book);
    }

    public int getLength(){
        return  books.size();
    }

    public Iterator iterator() {
        return  new BookShelfIterator();
    }

//    //普通模式
////    public ArrayList<Book> getBooks(){
////        return  books;
////    }

    class  BookShelfIterator implements  Iterator{
        //        private BookShelf bookShelf; //采用内部类,可以直接调用外部类方法,不用添加引用。
        private int index ;
        public BookShelfIterator() {
//            this.bookShelf=bookShelf;
            this.index = 0;
        }

        @Override
        public boolean hasNext() {
            if (index < getLength()){
                return  true;
            }else {
                return  false;
            }
        }
        @Override
        public Object next() {
            Book book  = getBookAt(index);
            index++;
            return book;
        }
    }

}

而我们获取这两个书架的书时,只需要调用两个书架的iterator()方法就可以获取到同样的Iterator对象,这个对象中都包含两个相同的方法hasNext()和Next(),这样我们就很方便的迭代输出了,并且我们不用关心每个书架里面是通过数组还是list存放书的。就像下面这样:

        ArrayList<Iterator> iterList = new ArrayList<>(); //存放Iterator
        BookShelf bookShelf = new BookShelf(4);//实例化第一个书架
        bookShelf.appendBook(new Book("Around the World in 80 Days"));
        bookShelf.appendBook(new Book("Bible"));
        bookShelf.appendBook(new Book("Daddy-Long-Legs"));
        bookShelf.appendBook(new Book("Cinderella"));
        Iterator it  = bookShelf.iterator();
        iterList.add(it);

        BookShelf1 bookShelf1 = new BookShelf1(4);//实例化第二个书架
        bookShelf1.appendBook(new Book("Around the World in 80 Days__"));
        bookShelf1.appendBook(new Book("Bible__"));
        bookShelf1.appendBook(new Book("Daddy-Long-Legs__"));
        bookShelf1.appendBook(new Book("Cinderella__"));
        Iterator it1  = bookShelf1.iterator();
        iterList.add(it1);
        for (int i = 0; i < iterList.size(); i++) {
            Iterator iterator = iterList.get(i);
            while (iterator.hasNext()){
                Book book = (Book) iterator.next();
                System.out.println(book.getName());
            }
        }
  • 完整代码

  请移步:https://github.com/yyc007/DesignPatterns/

  • 小结

  使用迭代器模式,可以帮助我们编写可以复用的类,当这个类发生改变时,不需要对其它的类进行修改或者很小的修改即可应对。就上面的书架例子来说,不管BookShelf如何变化,只要BookShelf返回的Iterator类的实例没有问题(hasNext方法和Next方法都可以正常工作),即使调用方不对迭代输出的While循环做任何修改都可以正常工作。

原文地址:https://www.cnblogs.com/hyyq/p/10116864.html

时间: 2024-07-30 16:35:29

设计模式——迭代器(Iterator)模式的相关文章

设计模式—迭代器Iterator模式

首先我们先模仿集合中ArrayList和LinkedList的实现.一个是基于数组的实现.一个是基于链表的实现,实现方式各有不同, 为了减少代码的耦合度,面向接口编程.定义Collection接口定义API规范. 可是在遍历集合中的元素时,由于数组和链表的遍历方式不一样,能不能统一处理呢? 再定义一个Iterator接口,让每一个子类集合都实现接口中的方法. 1.接口Collection.java public interface Collection<E> { public void add

Java 实现迭代器(Iterator)模式

类图 /** * 自定义集合接口, 类似java.util.Collection * 用于数据存储 * @author stone * */ public interface ICollection<T> { IIterator<T> iterator(); //返回迭代器 void add(T t); T get(int index); } /** * 自定义迭代器接口 类似于java.util.Iterator * 用于遍历集合类ICollection的数据 * @author

设计模式一:迭代器(Iterator)模式

一.什么是迭代器模式 说白了就是一种遍历集合中元素的一种设计模式,我们赶紧先来看一下例子 二.实现举例 这里我们举一个例子,是将书(Book)放置到书架中(BookShelf),一个迭代器,我们总共要写2个接口,分别是一个集合接口(Agreegate),一个迭代器接口(Iterator),两个接口对应的实现类,以及要被遍历的对象对应的类 三.迭代器模式(Iterator)的实现步骤: 1.我们需要有一个集合接口,在这个接口里面定义一个Iterator方法,用于生成遍历集合的迭代器(Iterato

Java设计模式之Iterator模式

分类: [java]2013-07-15 10:58 917人阅读 评论(0) 收藏 举报 所谓Iterator模式,即是Iterator为不同的容器提供一个统一的访问方式.本文以java中的容器为例,模拟Iterator的原理.参考:马士兵 Java设计模式 Iterator1.首先定义一个容器Collection接口. [java] view plaincopy package com.njupt.zhb.learn.iterator; public interface Collection

设计模式之Iterator模式

STL里的iterator就是应用了iterator模式. 一.什么是迭代模式 Iterator模式也叫迭代模式,是行为模式之一,它把对容器中包含的内部对象的访问委让给外部类,使用Iterator按顺序进行遍历访问的设计模式. 二.不使用迭代模式的应用 在应用Iterator模式之前,首先应该明白Iterator模式用来解决什么问题.或者说,如果不使用Iterator模式,会存在什么问题. 由容器自己实现顺序遍历.直接在容器类里直接添加顺序遍历方法 让调用者自己实现遍历.直接暴露数据细节给外部.

java 迭代器Iterator的介绍

 迭代对于我们搞Java的来说绝对不陌生.我们常常使用JDK提供的迭代接口进行Java集合的迭代. [java] view plain copy print? Iterator iterator = list.iterator(); while(iterator.hasNext()){ String string = iterator.next(); //do something } Iterator iterator = list.iterator(); while(iterator.ha

设计模式 - 迭代器模式(iterator pattern) Java 迭代器(Iterator) 详解

迭代器模式(iterator pattern) Java 迭代器(Iterator) 详解 本文地址: http://blog.csdn.net/caroline_wendy 参考迭代器模式(iterator pattern): http://blog.csdn.net/caroline_wendy/article/details/35254643 Java的标准库(util)中包含迭代器接口(iterator interface), import java.util.Iterator; 继承(

设计模式 --迭代器模式(Iterator)

能够游走于聚合内的每一个元素,同时还可以提供多种不同的遍历方式. 基本概念: 就是提供一种方法顺序访问一个聚合对象中的各个元素,而不是暴露其内部的表示. 使用迭代器模式的优点: 遍历集合或者数组: 忽略集合和数组的结构: 提供不同的遍历方式: 符合单一职责原则. 迭代器角色: 抽象迭代器:该接口必须定义实现迭代功能的最小定义方法集. 具体迭代器:迭代器接口Iterator的实现类.可以根据具体情况加以实现. 抽象聚合类:定义基本功能以及提供类似Iterator iterator()的方法. 具体

设计模式 - 组合模式(composite pattern) 迭代器(iterator) 详解

组合模式(composite pattern) 迭代器(iterator) 详解 本文地址: http://blog.csdn.net/caroline_wendy 参考组合模式(composite pattern): http://blog.csdn.net/caroline_wendy/article/details/36895627 在组合模式(composite pattern)添加迭代器功能, 遍历每一个组合(composite)的项. 具体方法: 1. 抽象组件类(abstract