美文网首页Java学习笔记程序员
Java 设计模式 -- 迭代器模式

Java 设计模式 -- 迭代器模式

作者: ghwaphon | 来源:发表于2016-10-04 10:18 被阅读1045次

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

    比如说,现在我们有两个聚合对象,一个是数组,一个是 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 设计模式 -- 迭代器模式

        本文链接:https://www.haomeiwen.com/subject/wsijyttx.html