设计模式1--Iterator模式(一个一个遍历)

1. 什么是迭代器模式?


迭代器模式,提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。
迭代器模式的本质是将遍历聚合对象中数据的行为提取出来,封装到一个迭代器中,通过专门的迭代器来遍历聚合对象的内部数据。

2. 迭代器用来做什么?


用于在数据集合中按照顺序遍历集合。

3.示例程序

  首先让我们看一段实现了Iterator模式的示例程序。这段示例程序的作用是讲书(Book)放置到书架(BookShelf)中,并将书名按顺序显示出来。

示例程序的类图

Aggregate接口

Aggregate接口是所要遍历的集合接口。实现了该接口的类成为一个可以保存多个元素的集合。就像数组一样。Aggregate有“使聚集”“集合”的意思

public interface Aggregaet{
    public abstract Iterator iteritor();
}

Iterator接口

Iterator接口用于遍历集合中的元素,其作用相当于循环语句中的循环变量

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

Book类

Book类表示书的类。但是这个类的作用有限,他可以做的事情只有一件--通过getName方法获取书的名字。书的名字是在外部调用Book类的构造函数并初始化Book类时,作为参数传递给Book的

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

BookShelf类

BookShelf类表示的是书架的类。由于需要将该类作为集合进行处理,因此它实现了Aggregate接口。代码中的implements Aggregate部分即表示了这一点。

public class BookShelf implements Aggregate{
    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 Iterator iterator(){
        return new BookShelfIterator(this);
    }

}

BookShelfIterator类

因为BookShelfIterator类需要发挥Iterator的作用,所以它实现了Iterator接口。

BookShlef字段表示BookShelfIterator所要遍历的书架。index字段表示迭代器当前所指向的书的下标。

public class BookShelfIterator implements{
    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;
    }
}

Main类

public class Main{
    public static void main(String[] args){
        BookShelf bookShelf = new BookShelf(4);
        bookShelf.appendBook(new Book("A"));
        bookShelf.appendBook(new Book("B"));
        bookShelf.appendBook(new Book("C"));
        bookShelf.appendBook(new Book("D"));
        Iterator it = bookShelf.iterator();
        while(it.hasNext()){
            Book book = (Book) it.next();
            System.out.println(book.geiName());
        }
    }
}

4.Iterator模式中登场的角色

Iterator(迭代器)

该角色负责定义按顺序逐个遍历元素的接口(API)。在示例程序中,由Iterator接口扮演这个角色,它定义了hasNext和next两个方法。其中,hasNext方法用于判断是否存在下一个元素,next方法则用于获取元素

ConcretelIterator(具体的迭代器)

该角色负责实现Iterator角色所定义的接口(API)。在示例程序中,由BookShelfIterator类扮演这个角色。该角色包含了遍历集合所必须的信息。

Aggregate(集合)

该角色负责定义创建Iterator角色的接口(API)。在示例程序中,由Aggregate接口扮演这个角色,它里面定义了iterator方法

ConcreteAggregate(具体的集合)

该角色负责实现Aggregate角色所定义的接口(API)。在示例程序中,由BookShelf类扮演这个角色,它实现了iterator方法。

5.拓展思路的要点

不管实现如何变化,都可以使用Iterator

  为什么要考虑引入Iterator这种复杂的设计模式?如果是数组,直接使用for循环语句进行遍历处理不是就可以了吗?为什么要在集合之外引入Iterator这个角色?

一个重要的理由是,引入Iterator后可以将遍历与实现分离开来

设计模式的作用就是帮助我们编写可复用的类。所谓“可复用”,就是指将类实现为“组件”,当一个组件发生变化时,不需要对其他的组件进行修改或是只需要很小的修改即可应对。

难以理解抽象类和接口

如果只是使用具体的类来解决问题,很容易导致类之间的强耦合,这些类也难以作为组件被再次利用。为了弱化类之间的耦合,进而使得类更加容易作为组件被再次利用,我们需要引入抽象类和接口。

Aggregate和Iterator的对应

仔细回忆我们是如何把BookShlefItorator类定义为BookShelf类的ConcreteIterator角色的。BookShelfIterator类知道BookShelf是如何实现的,也正是因为如此,我们才能调用来获取下一本书的getBookAt方法。

也就是说,如果BookShelf的实现发生了改变,即getBookAt方法这个接口(API)发生变化时,我们必须修改BookShelfIterator这两个类的对应。

迭代器的种类多种多样

从最后开始向前遍历

既可以从前向后遍历,也可以从后向前遍历

指定下标进行“跳跃式”遍历

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值