今天开始重新学习设计模式,记录一下。
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
可以看到全部书已被按追加顺序遍历打印出,但可以看到我们自定义的迭代器耦合度非常非常高,难以再次利用,甚至本例根本无法再次利用,这很糟糕,再后面会对该例进行一步优化,有时间会记录一下。