设计模式之Iterator模式

本文介绍了设计模式中的Iterator模式,通过一个书架类和书类的例子展示了如何实现自定义迭代器进行遍历。代码示例中,创建了书架类BookShelf和书类Book,并实现了接口Aggregate和Iterator,允许按顺序遍历书架上的图书。然而,自定义迭代器的高耦合度限制了其复用性,文章提出后续将对此进行优化。
摘要由CSDN通过智能技术生成

今天开始重新学习设计模式,记录一下。

Iterator模式

看到Iterator,第一反应肯定已经想到了各种遍历,数组,集合。该模式也比较简单,相当于自己实现了一点迭代器功能,直接上代码,代码中有注释。

import java.util.Arrays;

/**
 * @author lenovo
 * @title: Main
 * @projectName LearnDesignMode
 * @description: TODO
 * @date 2022/5/221:18
 */
public class Main {
    public static void main(String[] args) {
        //本例介绍的是Iterator模式,顾名思义,是一种和遍历有关的模式

        //遍历数组 通常这样做
        int[] arr = {3, 4, 5, 12, 7, 2, 23, 1};
        for(int i=0; i<arr.length; ++i) {
            System.out.println("for--" + "第" + i + "个数为:" + arr[i]);
        }

        System.out.println();

        //或者使用foreach(但foreach尽可能用来查看,而不是修改元素)
        int curIndex = 0;
        for(int i : arr) {
            System.out.println("foreach--" + "第" + curIndex++ + "个数为:" + i);
        }

        System.out.println();

        //还有第三种通过Arrays工具类的toString和deepToString方法
        int[][] arr2 = {{3, 4, 16}, {13, 2}, {2, 43, 4}};

        System.out.println("Arrays.toString(一维数组)--" + Arrays.toString(arr));
        System.out.println("Arrays.toString(多维数组)--" + Arrays.toString(arr2));
        System.out.println("Arrays.deepToString--" + Arrays.deepToString(arr2));
    }
}

运行结果如下:

for--第0个数为:3
for--第1个数为:4
for--第2个数为:5
for--第3个数为:12
for--第4个数为:7
for--第5个数为:2
for--第6个数为:23
for--第7个数为:1

foreach--第0个数为:3
foreach--第1个数为:4
foreach--第2个数为:5
foreach--第3个数为:12
foreach--第4个数为:7
foreach--第5个数为:2
foreach--第6个数为:23
foreach--第7个数为:1

Arrays.toString(一维数组)--[3, 4, 5, 12, 7, 2, 23, 1]
Arrays.toString(多维数组)--[[I@1b6d3586, [I@4554617c, [I@74a14482]
Arrays.deepToString--[[3, 4, 16], [13, 2], [2, 43, 4]]

接下来具体看一个例子:假如有一个书架,直接执行加入图书,遍历图书的功能,这时就可以抽象出两个类,分别是书架类,书类。为了实现迭代,我们要求书架类实现接口Aggregate,该接口很简单,只有一个返回类型为我们自定义的迭代器类型的方法,如下:

public interface Aggregate {  //表示集合要实现的接口
    public abstract Iterator iterator();
}

顺便看下迭代器接口定义的规范:

public interface Iterator {  //遍历集合的接口
    //判断是否还有下一个元素
    public abstract boolean hasNext();

    //获取下一个元素
    public abstract Object next();
}

然后我们要去定义书类和书架类,首先是书类:

public class Book {
    private String name;

    public Book(String name) {
        this.name = name;
    }

    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
}

可以看到书类是很简单的一个pojo类,然后是书架类:

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) {
        if(index >= 0 && index < books.length) {
            return books[index];
        }
        return null;
    }

    public boolean appendBook(Book book) {
        if(this.last == this.books.length) {
            return false;
        }
        this.books[last++] = book;
        return true;
    }

    public int getLength() {
        return this.last;
    }

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

书架类的基本功能有按索引获取图书,追加图书,获取当前书的数量,返回该书架类的迭代器。接下来来看书架类迭代器的具体实现:

public class BookShelfIterator implements Iterator{
    private BookShelf bookShelf;
    private int index;

    public BookShelfIterator(BookShelf bookShelf) {
        this.bookShelf = bookShelf;
        this.index = 0;
    }

    @Override
    public boolean hasNext() {
        if(index < bookShelf.getLength()) {
            return true;
        }
        return false;
    }

    @Override
    public Object next() {
        if(hasNext()) {
            return bookShelf.getBookAt(index++);
        }
        return null;
    }
}

总体还是比较简单的,来测试一下:

Java Learn
MySql Learn
Spring Learn
Spring MVC Learn

可以看到全部书已被按追加顺序遍历打印出,但可以看到我们自定义的迭代器耦合度非常非常高,难以再次利用,甚至本例根本无法再次利用,这很糟糕,再后面会对该例进行一步优化,有时间会记录一下。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值