设计模式之迭代器模式

一、什么是迭代器模式

迭代器模式,提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部细节。

迭代器模式,也叫游标模式,属于行为型设计模式。

二、迭代器模式类图

设计模式之迭代器模式插图

三、迭代器模式角色

  • 迭代器角色(Iterator): 定义按顺序逐个遍历元素的接口,主要有hasNext和next两个方法。
  • 具体迭代器角色(ConcreteIterator): 实现Iterator接口,实现对聚合对象的遍历,并记录当前游标的索引位置。
  • 聚合角色(Aggregate):定义创建Iterator角色的接口,提供获取聚合对象的方法,还有添加元素、删除元素等方法。
  • 具体聚合角色(ConcreteAggregate):实现Aggregate接口,它会创建出具体的Iterator角色,实现获取聚合对象的方法、添加元素、删除元素等方法。

四、迭代器模式优缺点

优点:

  1. 支持以不同的方式遍历一个聚合对象。
  2. 简化了聚合的接口,通过迭代器来遍历聚合对象。
  3. 在同一个聚合上可以有多个遍历。

缺点:

  1. 以复杂的方式同时遍历两个不同的数据结构时,迭代器实际上可能会成为累赘。
  2. 增加新的聚合类就需要增加新的迭代器类,类的个数成对增加,一定程度上增加到了系统维护的复杂性。
  3. 对于比较简单的遍历,使用迭代器模式显得较为繁琐。

五、迭代器模式demo示例

1、Demo需求

使用迭代器模式定义一个迭代器,迭代器元素定义为泛型,存储元素的集合使用List。例如:使用书本类(书名及价格)作为迭代器元素,聚合类含有添加元素、删除元素方法,并返回迭代器对象。最后使用迭代器对List集合进行遍历。

2、接口定义

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
 * 抽象迭代器角色:迭代器接口
 */ public interface Iterator<E> {
 
    /**
     * 是否有下一个元素
     * @return
     */     boolean hasNext();
 
    /**
     * 获取下一个元素
     * @return
     */     E next();
 
    /**
     * 获取第一个元素
     * @return
     */     E first();
 
    /**
     * 获取最后一个元素
     * @return
     */     E last();
 
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
/**
  *  抽象聚合角色:聚合接口
  */ public interface Aggregate<E> {
  
     /**
      * 向集合中添加一个元素
      * @param e
      */     void add(E e);
  
     /**
      * 从集合中删除一个元素
      * @param e
      */     void remove(E e);
  
     /**
      * 返回一个迭代器对象
      * @return
      */     Iterator<E> createMyIterator();
 }

3、实现类定义

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/**
 * @Description: 具体迭代器角色:数组迭代器
 **/ public class MyIterator<E> implements Iterator<E> {
 
    // 存放对象的数组
    private List<E> list;
 
    // 当前索引所在的下标位置
    private int position = 0;
 
    /**
     * 初始化list集合数据
     * @param list
     */     public MyIterator(List<E> list) {
        this.list = list;
    }
 
    /**
     * 判断是否有下一个元素
     * @return
     */     @Override
    public boolean hasNext() {
        return list.size() > position;
    }
 
    /**
     * 获取下一个元素对象
     * @return
     */     @Override
    public E next() {
        E e = list.get(position);
        position++;
        return e;
    }
 
    /**
     * 获取第一个元素对象
     * @return
     */     @Override
    public E first() {
        return list.get(0);
    }
 
    /**
     * 获取最后一个元素对象
     * @return
     */     @Override
    public E last() {
        if (list.size() == 0) {
            return null;
        }
        return list.get(list.size() - 1);
    }
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
  * @Description: 具体聚合角色:实现聚合功能(添加元素、删除元素、返回迭代器对象等)
  **/ public class MyAggregate<E> implements Aggregate<E> {
 
     // 集合对象
     private List<E> list = new ArrayList<>();
  
     /**
      * 添加元素
      * @param e
      */     @Override
     public void add(E e) {
         list.add(e);
     }
  
     /**
      * 删除元素
      * @param e
      */     @Override
     public void remove(E e) {
         list.remove(e);
     }
  
     /**
      * 返回一个迭代器对象
      * @return
      */     @Override
     public Iterator<E> createMyIterator() {
         return new MyIterator<>(list);
     }
 }
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/**
  * @Description: 书本类,充当元素对象
  **/ public class Book {
 
     private String name;
     private Double price;
  
     public Book(String name, Double price) {
         this.name = name;
         this.price = price;
     }
  
     public String getName() {
         return name;
     }
  
     public void setName(String name) {
         this.name = name;
     }
  
     public Double getPrice() {
         return price;
     }
  
     public void setPrice(Double price) {
         this.price = price;
     }
  
     @Override
     public String toString() {
         return "Book{" +
                 "name='" + name + ''' +
                 ", price=" + price +
                 '}';
     }
 }

4、测试

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
  * @Description: 迭代器模式客户端测试类
  **/ public class Client {
 
     public static void main(String[] args) {
         //构建聚合对象
         Aggregate<Book> aggregate = new MyAggregate<>();
         //添加书本对象
         aggregate.add(new Book("计算机基础",80.00));
         aggregate.add(new Book("java编程",60.00));
         aggregate.add(new Book("python入门",50.00));
         aggregate.add(new Book("PHP从入门到放弃",30.00));
  
         //获取迭代器对象
         Iterator<Book> iterator = aggregate.createMyIterator();
         //打印第一本书
         System.out.println("打印第一本书: "+iterator.first());
         //打印最后一本书
         System.out.println("打印最后一本书: "+iterator.last());
         // 循环打印书本信息
         while (iterator.hasNext()){
             System.out.println(iterator.next());
         }
     }
 }

控制台日志:

1
2
3
4
5
6
打印第一本书: Book{name='计算机基础', price=80.0}
打印最后一本书: Book{name='PHP从入门到放弃', price=30.0}
Book{name='计算机基础', price=80.0}
Book{name='java编程', price=60.0}
Book{name='python入门', price=50.0}
Book{name='PHP从入门到放弃', price=30.0}

发表评论

欢迎阅读『设计模式之迭代器模式|Java、设计模式|Nick Tan-梓潼Blog』