一、前言

本篇主题为行为型模式中的第三个模式–迭代器模式。上篇 Java 设计模式主题为《Java 设计模式之命令模式(十四)》

二、简单介绍

# 2.1 定义

迭代器模式是行为模式之一,它把对容器中包含的内部对象的访问委让给外部类(此外部类是指非自身的类),使用 Iterator(遍历)按顺序进行遍历访问的设计模式。

# 2.2 参与角色

  1. 迭代器接口(Iterator):该接口必须定义实现迭代功能的最小定义方法集。比如提供 hasNext() 和 next() 方法。

  2. 迭代器实现类(ConcreteIterator):迭代器接口 Iterator 的实现类。可以根据具体情况加以实现。

  3. 容器接口(Aggregate):定义基本功能以及提供类似 Iterator iterator() 的方法。

# 2.3 应用场景

  1. 访问一个聚合对象的内容而无需暴露它的内部表示。

  2. 支持对聚合对象的多种遍历。

  3. 为遍历不同的聚合结构提供一个统一的接口。

三、实现方式

我们以坐车买票为例,乘客上车后,由售票员对每个乘客进行售票操作(相当于遍历操作)。

售票员接口(Iterator):

  1. public interface Conductor {
  2. /**
  3. * 将游标指向第一个元素
  4. */
  5. void first();
  6. /**
  7. * 将游标指向下一个元素
  8. */
  9. void next();
  10. /**
  11. * 判断是否存在下一个元素
  12. * @return
  13. */
  14. boolean hasNext();
  15. /**
  16. * 判断是否是第一个元素
  17. * @return
  18. */
  19. boolean isFirst();
  20. /**
  21. * 判断是否是最后一个元素
  22. * @return
  23. */
  24. boolean isLast();
  25. /**
  26. * 获取当前游标指向的对象
  27. * @return
  28. */
  29. Object getCurrentObj();
  30. }

巴士接口(Aggregate):

  1. public interface Bus {
  2. public void getOn(Object obj);
  3. public void getOff(Object obj);
  4. public Conductor conductor();
  5. }

机场大巴(Aggregate 实现类):

  1. public class SkyBus implements Bus{
  2. private List<Object> list = new ArrayList<Object>();
  3. @Override
  4. public void getOn(Object obj) {
  5. this.list.add(obj);
  6. }
  7. @Override
  8. public void getOff(Object obj) {
  9. this.list.remove(obj);
  10. }
  11. @Override
  12. public Conductor conductor() {
  13. return new BusConductor();
  14. }
  15. public List<Object> getList() {
  16. return list;
  17. }
  18. public void setList(List<Object> list) {
  19. this.list = list;
  20. }
  21. // 使用内部类定义迭代器,可以直接使用外部类的属性
  22. private class BusConductor implements Conductor {
  23. /**
  24. * 定义游标用于记录遍历时的位置
  25. */
  26. private int cursor;
  27. @Override
  28. public void first() {
  29. cursor = 0;
  30. }
  31. @Override
  32. public Object getCurrentObj() {
  33. return list.get(cursor);
  34. }
  35. @Override
  36. public boolean hasNext() {
  37. return cursor < list.size();
  38. }
  39. @Override
  40. public boolean isFirst() {
  41. return cursor == 0;
  42. }
  43. @Override
  44. public boolean isLast() {
  45. return cursor == (list.size() - 1);
  46. }
  47. @Override
  48. public void next() {
  49. if (cursor < list.size()) {
  50. cursor++;
  51. }
  52. }
  53. }
  54. }

在 Aggregate 实现类中定义内部类实现 Iterator 接口。

客户端:

  1. public class Client {
  2. public static void main(String[] args) {
  3. Bus bus = new SkyBus();
  4. bus.getOn("张三");
  5. bus.getOn("李四");
  6. bus.getOn("王五");
  7. Conductor iter = bus.conductor();
  8. while(iter.hasNext()){
  9. System.out.println(iter.getCurrentObj() + "乘客,请买票!");
  10. iter.next();
  11. }
  12. }
  13. }

打印结果:

  1. 张三乘客,请买票!
  2. 李四乘客,请买票!
  3. 王五乘客,请买票!

UML 类图表示如下: