神刀安全网

Java 设计模式 — 迭代器模式

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

比如说,现在我们有两个聚合对象,一个是数组,一个是 ArrayList, 利用这两个对象分别存储文理科课程信息,像下面这样。

public class LiberalLessons {      public static final int MAX_LESSONS = 3;     private int numberOfLessons = 0;     private String[] lessons;      public LiberalLessons() {         lessons = new String[MAX_LESSONS];         addLessons("Political");         addLessons("Geography");         addLessons("History");     }      private void addLessons(String lesson) {         lessons[numberOfLessons] = lesson;         numberOfLessons++;     }      public String[] getLessons() {         return lessons;     } }  public class ScienceLessons {     private ArrayList<String> lessons;      public ScienceLessons() {         lessons = new ArrayList<>();         addLessons("Physical");         addLessons("Chemical");         addLessons("Biological");     }      private void addLessons(String lesson) {         lessons.add(lesson);     }      public ArrayList getLessons() {         return lessons;     } }

可见,以上我们将信息保存在了不同的聚合对象中,那么如果我们想要同时打印文理科的课程,该怎么办呢?

public class PrintHelper {     private LiberalLessons liberalLessons;     private ScienceLessons scienceLessons;      public PrintHelper(LiberalLessons liberalLessons, ScienceLessons scienceLessons) {         this.liberalLessons = liberalLessons;         this.scienceLessons = scienceLessons;     }      public void print() {         printLiberalLessons();         printScienceLessons();     }      private void printLiberalLessons() {         String[] lessons = liberalLessons.getLessons();         System.out.println("Liberal Lessons : ");         for (int i = 0; i < LiberalLessons.MAX_LESSONS; i++) {             System.out.print(lessons[i] + "/t");         }         System.out.println();     }      private void printScienceLessons() {         ArrayList<String> lessons = scienceLessons.getLessons();         System.out.println("Science Lessons : ");         for (int i = 0; i < lessons.size(); i++) {             System.out.print(lessons.get(i) + "/t");         }         System.out.println();     } }  public class Client {     public static void main(String[] args) {         LiberalLessons liberalLessons = new LiberalLessons();         ScienceLessons scienceLessons = new ScienceLessons();          PrintHelper printHelper = new PrintHelper(liberalLessons, scienceLessons);         printHelper.print();     } }

可见,在这里我又多写了一个辅助类 PrintHelper, 这样可以减少主函数中的代码量,我个人不太喜欢在主函数写太多的代码。

来看看,由于我们使用了不同的聚合对象,导致我们不得不区别对待,如果有一种方法,能够让我们不管是针对哪种聚合对象都可以进行相同的操作就好了,这正是迭代器应该做的工作。

首先,我们看看 java.util.Iterator 接口

public interface Iterator<E> {     boolean hasNext();     E next();     void remove(); }

hasNext() 方法返回一个布尔值,让我们知道是否还有更多的元素。
next() 方法返回下一个元素的值。
remove() 用于删除由 next() 方法返回的最后一项。

下面我们就利用Iterator 对以上代码进行改写。

public class LiberalIterator implements Iterator<String> {      private String[] lessons;     private int position = 0;      public LiberalIterator(String[] lessons) {         this.lessons = lessons;     }      @Override     public boolean hasNext() {         if (position >= lessons.length) {             return false;         }         return true;     }      @Override     public String next() {         String lesson = lessons[position];         position += 1;         return lesson;     }      @Override     public void remove() {         throw new UnsupportedOperationException("You can not remove element !");     } }

我们针对文科课程类写了一个迭代器,在 remove() 方法中我们抛出了一个异常,表示我们不希望客户端通过迭代器删除元素。实际上我们也只需要写这么一个迭代器类,因为在 ScienceLessons 类中我们使用的是 ArrayList ,它是自带 Iterator 的,我们只需要调用 iterator() 方法即可。

接下来,我们就将 LiberalLessonsScienceLessons 中的 getLessons() 方法进行改写,写成 createIterator() 方法。

public Iterator<String> createIterator() {     return new LiberalIterator(lessons); } public Iterator<String> createIterator() {     return lessons.iterator(); }

现在再看看我们的 PrintHelper 该怎么书写代码。

public class PrintHelper {     private LiberalLessons liberalLessons;     private ScienceLessons scienceLessons;      public PrintHelper(LiberalLessons liberalLessons, ScienceLessons scienceLessons) {         this.liberalLessons = liberalLessons;         this.scienceLessons = scienceLessons;     }      public void print() {         System.out.println("Liberal Lessons : ");         Iterator<String> liberalIterator = liberalLessons.createIterator();         print(liberalIterator);         System.out.println();          System.out.println("Science Lessons : ");         Iterator<String> scienceIterator = scienceLessons.createIterator();         print(scienceIterator);         System.out.println();       }      private void print(Iterator<String> iterator) {         while (iterator.hasNext()) {             System.out.print(iterator.next() + "/t");         }     } }

这样的话,我们就可以不必区分聚合对象,只需要根据类中提供的迭代器就可以访问元素,而且这个时候我们也不知道类的内部用的是哪种聚合类型。

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » Java 设计模式 — 迭代器模式

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址