设计模式之迭代器模式

一、什么是迭代器模式

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

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

二、迭代器模式类图

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

三、迭代器模式角色

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

四、迭代器模式优缺点

优点:

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

缺点:

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

五、迭代器模式demo示例

1、Demo需求

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

2、接口定义

 /**
  * 抽象迭代器角色:迭代器接口
  */ public interface Iterator<E> {
 
     /**
      * 是否有下一个元素
      * @return
      */     boolean hasNext();
 
     /**
      * 获取下一个元素
      * @return
      */     E next();
 
     /**
      * 获取第一个元素
      * @return
      */     E first();
 
     /**
      * 获取最后一个元素
      * @return
      */     E last();
 
 }
/**
  *  抽象聚合角色:聚合接口
  */ public interface Aggregate<E> {
 
     /**
      * 向集合中添加一个元素
      * @param e
      */     void add(E e);
 
     /**
      * 从集合中删除一个元素
      * @param e
      */     void remove(E e);
 
     /**
      * 返回一个迭代器对象
      * @return
      */     Iterator<E> createMyIterator();
 }

3、实现类定义

 /**
  * @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);
     }
 }
/**
  * @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);
     }
 }
/**
  * @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、测试

/**
  * @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());
         }
     }
 }

控制台日志:

打印第一本书: 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}

发表评论