設計模式之迭代器模式

0x01.定義與類型

  • 定義:提供一種方法,順序訪問一個集合對象中的各個元素,而又不暴露該對象的內部表示。
  • 類型:行爲型

通常狀況,咱們本身開發時不多自定義迭代器,由於java自己已經把迭代器作到內部中了(好比:經常使用的list和set中都內置了迭代器)。
固然,若是真有這種需求須要咱們自定義迭代器的話,能夠參考jdk的迭代器實現方式來實現本身的迭代器。
迭代器是能夠從前日後,或者從後往前遍歷的。
爲遍歷不一樣彙集結構提供如:開始,下一個,是否有下一個,是否結束,當前哪個等等的一個統一接口。html

  • 迭代器模式UML類圖

iterator1.png

  • 對應的Java實現
/**
 * 聚合類接口
 */
public interface Aggregate {
    Iterator createIterator();
}


/**
 * 具體的迭代器
 */
public interface Iterator {

    boolean hasNext();

    Object next();
}

/**
 * 聚合實現類
 */
public class ConcreteAggregate implements Aggregate {

    private List<Object> contains;

    public ConcreteAggregate () {
        contains = new ArrayList<>();
    }

    public boolean add (Object object) {
        return contains.add(object);
    }

    public boolean remove(Object object) {
        return contains.remove(object);
    }

    @Override
    public Iterator createIterator() {
        return new ConcreteIterator(this.contains);
    }
}


/**
 * 迭代器接口
 */
public class ConcreteIterator implements Iterator {

    private List<Object> contains;

    private int position = 0;

    private Object object;

    public ConcreteIterator(List<Object> contains) {
        this.contains = contains;
    }


    @Override
    public boolean hasNext() {
        return contains.size() > position;
    }

    @Override
    public Object next() {
        object = contains.get(position);
        position ++;
        return object;
    }
}
  • 測試與應用類
/**
 * 應用與測試
 */
public class Test {

    public static void main(String[] args) {
        ConcreteAggregate aggregate = new ConcreteAggregate();
        aggregate.add(new Object());
        aggregate.add(new Object());
        aggregate.add(new Object());

        Iterator iterator = aggregate.createIterator();

        while (iterator.hasNext()) {
            System.out.println(iterator.next().toString());
        }

    }
}
  • 輸入日誌,遍歷了三個地址
java.lang.Object@1540e19d
java.lang.Object@677327b6
java.lang.Object@14ae5a5
  • 迭代器模式主要包含如下角色。前端

    • 抽象聚合(Aggregate)角色:定義存儲、添加、刪除聚合對象以及建立迭代器對象的接口。
    • 具體聚合(ConcreteAggregate)角色:實現抽象聚合類,返回一個具體迭代器的實例。
    • 抽象迭代器(Iterator)角色:定義訪問和遍歷聚合元素的接口,一般包含 hasNext()、first()、next() 等方法。
    • 具體迭代器(Concretelterator)角色:實現抽象迭代器接口中所定義的方法,完成對聚合對象的遍歷,記錄遍歷的當前位置。

0x02.使用場景

  • 訪問一個集合對象的內容而無需暴露它的內部表示
  • 爲遍歷不一樣的集合結構提供一個統一的接口

0x03.優缺點

1.優勢

  • 分離了集合對象的遍歷行爲

2.缺點

  • 類的個數成對增長

0x04.相關設計模式

  • 迭代器模式和訪問者模式

0x05.樣例

課程的聚合類以及迭代器的應用
/**
 * 彙集類接口
 */
public interface CourseAggregate {

    void addCourse(Course course);

    void removeCourse(Course course);

    CourseIterator getCourseIterator();
}


/**
 * 迭代器接口
 */
public interface CourseIterator {

    Course nextCourse();

    boolean hasNextCourse();

}

/**
 * 具體的彙集類
 */
public class CourseAggregateImpl implements CourseAggregate {


    private List<Course> courseList;

    public CourseAggregateImpl () {
        courseList = new ArrayList<>();
    }

    @Override
    public void addCourse(Course course) {
        courseList.add(course);
    }

    @Override
    public void removeCourse(Course course) {
        courseList.remove(course);
    }

    @Override
    public CourseIterator getCourseIterator() {
        return new CourseIteratorImpl(courseList);
    }
}


/**
 * 具體的迭代器
 */
public class CourseIteratorImpl implements CourseIterator {

    private List<Course> courseList;

    private int position;

    private Course course;


    public CourseIteratorImpl(List<Course> courseList) {
        this.courseList = courseList;
    }

    @Override
    public Course nextCourse() {
        System.out.println("返回的課程,位置是: " + position);
        course = courseList.get(position);
        position ++;
        return course;
    }

    @Override
    public boolean hasNextCourse() {
        return position < courseList.size();
    }
}

/**
 * 課程實體類
 */
public class Course {

    private String name;

    public Course(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}
  • 測試與應用類
/**
 * 應用與測試類
 */
public class Test {

    public static void main(String[] args) {
        Course course1 = new Course("Java電商一期");
        Course course2 = new Course("Java電商二期");
        Course course3 = new Course("Java設計模式精講");
        Course course4 = new Course("Python課程");
        Course course5 = new Course("算法課程");
        Course course6 = new Course("前端課程");

        CourseAggregate courseAggregate = new CourseAggregateImpl();

        courseAggregate.addCourse(course1);
        courseAggregate.addCourse(course2);
        courseAggregate.addCourse(course3);
        courseAggregate.addCourse(course4);
        courseAggregate.addCourse(course5);
        courseAggregate.addCourse(course6);

        System.out.println("-----課程列表------");
        printCourse(courseAggregate);

        courseAggregate.removeCourse(course4);
        courseAggregate.removeCourse(course5);

        System.out.println("------刪除操做以後的課程列表-----");
        printCourse(courseAggregate);

    }

    private static void printCourse (CourseAggregate courseAggregate) {

        CourseIterator courseIterator = courseAggregate.getCourseIterator();

        while (courseIterator.hasNextCourse()) {
            Course course = courseIterator.nextCourse();
            System.out.println("-----> " + course.getName());
        }

    }

}
  • 輸出結果
-----課程列表------
返回的課程,位置是: 0
-----> Java電商一期
返回的課程,位置是: 1
-----> Java電商二期
返回的課程,位置是: 2
-----> Java設計模式精講
返回的課程,位置是: 3
-----> Python課程
返回的課程,位置是: 4
-----> 算法課程
返回的課程,位置是: 5
-----> 前端課程
------刪除操做以後的課程列表-----
返回的課程,位置是: 0
-----> Java電商一期
返回的課程,位置是: 1
-----> Java電商二期
返回的課程,位置是: 2
-----> Java設計模式精講
返回的課程,位置是: 3
-----> 前端課程
  • 樣例UML類圖

iterator2.png

0x06.源碼中的迭代器

  • java.util.Iterator
  • cursor

0x07.代碼地址

0x08.推薦閱讀

相關文章
相關標籤/搜索