zoukankan      html  css  js  c++  java
  • GOF设计模式——Iterator模式

             Iterator,自然而然想到的是用于集合遍历的迭代器Iterator,没错Iterator模式就是指这个意思。

            先来看一段代码:

    int[] array = new int[10];
    for(int i = 0; i<array.length; i++){
        System.out.println(array[i]);
    }

          上面是编程里面很常见的遍历数组的用法,假如我不直接操作array对象,然后将用于表示下标的 i 抽象化,通用化,将遍历的动作交给迭代器,那么这种模式就叫做Iterator模式。

            举一个示例,有一个书架和一些书,每一本书作为一个个体(实例),书架可以理解为这些个体的集合。

    介绍一下上面的各个“东西”:

    Aggregate:一个集合接口,凡是实现这个接口的iterator方法,就具有集合的功能;

    Iterator:一个具有遍历功能的迭代器接口,里面定义了迭代需要的方法;

    BookShelf:集合的具体实现类;

    BookShelfIterator:迭代器接口的具体实现类;

    Book:个体类。

    1、Aggregate接口定义:

    public interface Aggregate{
        public abstract Iterator iterator();
    }

    2、Iterator接口:

    public interface Interator{
        public abstract boolean hasNext();
        public abstract Object next();
    }

    里面很简单,只定义了两个方法:hasNext和next。使用过集合迭代器的小伙伴都知道,hasNext用于判断是否存在元素,next获取当前元素的同时,将下标指向下一个元素。

    3、BookShelf类定义

    public class BookShelf implement Aggregate{
        private Book[] books;
        private int last = 0;
     
        public BookShelf(int maxsize){
            books = new Book[maxsize];
        }
     
        public Book getBookAt(int index){
            return books[index];
        }
     
        public void appendBook(Book book){
            books[last] = book;
            last++;
        }
     
        public int getLength(){
            return last;
        }
     
        public Iterator iterator(){
            return new BookShelfIterator(this);
        }
     
    }

    构造方法根据参数创建指定大小的Book数组,appendBook用于给数组添加元素,getLength获取当前数组长度(正确来说是当前数组最后一个元素的下标+1),另外,还实现了Aggregate的抽象方法iterator(),上面也提及到,只要一个类实现了Aggregate接口,就具有集合的功能,即遍历功能,在这里,只是用于创建迭代器的实现类BookShelfIterator,遍历的具体功能交给BookShelfIterator实现类去实现。

    4、BookShelfIterator类定义

    public class BookShelfIterator implements Iterator{
        private BookShelf bookShelf;
        private int index;
     
        public BookShelfIterator(BookShelf bookShelf){
            this.bookShelf = bookShelf;
            this.index = 0;
        }
     
        public boolean hasNext(){
            if(index < bookShelf.getLength()){
                return true;
            } else {
                return false;
            }
        }
     
        public Object next(){
            Book book = bookShelf.getBookAt(index);
            index++;
            return book;
        }
    }

    很简单,构造方法里将BookShelf对象作为参数,当前属性指向BookShelf对象,用于操作获取BookShelf元素,以及BookShelf长度。hashNext的实现逻辑只是对BookShelf对象的长度做一个判断,如果当前下标小于BookShelf长度,那么就返回true,否则,返回false。next方法,除了返回指定下标元素之外,还将下标向后推移了一位,即next实现了两个功能。

    5、Book类定义

    public class Book{
        private String name;
     
        public Book(String name){
            this.name = name;
        }
     
        public String getName(){
            return name;
        }
    }

    至于测试方法,这里不写出来了。

            我们就会发现,开头那段for代码里面的i++,就相当于next()方法里面的index++操作,都是用于指向下一位元素。上面代码的实现效果相当于ArrayList,不过BookShelf这个集合类这样子写,是会出问题的,ArrayList对象是可以“无限”添加元素,但是BookShelf最大只能添加maxsize个元素,所以可以进行改进。

    改进后的BookShelf类:

    public class BookShelf implement Aggregate{
        private List Books;
     
        public BookShelf(int initialsize){
            books = new ArrayList(initialsize);
        }
     
        public Book getBookAt(int index){
            return (Book)books.get(index);
        }
     
        public void appendBook(Book book){
            books.add(book);
        }
     
        public int getLength(){
            return books.size();
        }
     
        public Iterator iterator(){
            return new BookShelfIterator(this);
        }
     
    }

    至于为什么要使用Iterator呢?一个重要原因是,可以将遍历与实现分离开来。对BookShelf对象进行遍历的时候,会用到下面代码:

    Iterator it = bookShelf.iterator();
    while(it.hasNext()){
        Book book = (Book)it.next();
        System.out.println(book.getName());
    }

    遍历的过程,根本没有使用过BookShelf类的方法,完全不需要理会BookShelf的实现,也不知道BookShelf怎么实现,但是Iterator知道,所以只需要调用Iterator的方法就可以实现遍历BookShelf集合的效果。这样设计的好处就是,可以根据的实际业务需求来增加遍历的功能,使得原有的代码不改动或少改,达到一个低耦合的效果。

  • 相关阅读:
    python学习第十五天
    python学习第十三、十四天
    python学习第十二天
    python学习第j十一天
    python学习第十天
    ViewController push的自定义动画
    iOS 判断设备是否越狱
    iOS
    OBJC字面量
    ios8 share Extension 分享扩展
  • 原文地址:https://www.cnblogs.com/SysoCjs/p/10326748.html
Copyright © 2011-2022 走看看