Iterator pattern of design pattern

Time:2022-6-11

Iterator mode, also known as cursor mode, belongs to behavior mode; It refers to providing some methods to access a series of data in the aggregate object in sequence without exposing the internal appearance of the aggregate object. The iterator pattern is realized by separating the traversal behavior of the aggregated object and abstracting it into an iterator class. Its purpose is to make the external code access the aggregated internal data transparently without exposing the internal structure of the aggregated object.

Iterator pattern is one of the most common design patterns, and it is also one of several design patterns widely used in Java language API. In the collection framework of the Java language, iterators are widely used to traverse the aggregated elements.

The UML class diagram of iterator pattern is as follows:

It can be seen from the above figure that the iterator pattern involves four roles: Abstract aggregate role, concrete aggregate role, abstract iterator role, and concrete iterator role:

  1. Abstract aggregate role: defines interfaces for storing, adding, deleting aggregate objects, and creating iterator objects.
  2. Concreteaggregate role: implements an abstract aggregate class and returns an instance of a concrete iterator.
  3. Abstract iterator role: defines interfaces for accessing and traversing aggregation elements, usually including hasnext (), first (), next (), and other methods.
  4. Concreteiterator role: implement the methods defined in the abstract iterator interface, complete the traversal of aggregate objects, and record the current traversal position.

Iterators are divided intoActive iterationandPassive iteration, mainly relative to the client. If the client controls the process of iteration, such iteration is active iteration, on the contrary, it is passive iteration. The client using active iteration will obviously call the iterator’s next () and other iteration methods to iterate forward in the process of traversal, while the client using passive iteration will obviously not call the iteration method, but the iterator will promote the traversal process by itself. Most of our development processes use active iterations.

Examples of schools and departments

In a university, there are many colleges, and each college has many departments. If you want to know how many colleges this university consists of and how many majors a college consists of, you can use the iterator pattern.

The UML class diagram of the system is as follows:

Abstract aggregate role:

package com.charon.iterator;

import java.util.Iterator;

/**
 * @className: College
 *@description: College
 * @author: charon
 * @create: 2022-03-27 14:52
 */
public interface College {

    /**
     *Get the name of the College
     * @return
     */
    String getName();

    /**
     *Add College
     *@param name name
     *@param desc description
     */
    void addDepartment(String name,String desc);

    /**
     *Returns an iterator object for traversal
     * @return
     */
    Iterator createIterator();
}

Specific aggregate roles:

package com.charon.iterator;

import java.util.Iterator;

/**
 * @className: ComputerCollege
 *@description: Computer College
 * @author: charon
 * @create: 2022-03-27 14:56
 */
public class ComputerCollege implements College{

    Department[] departments;

    /**
     *Number of lower series
     */
    int departmentNum;

    public ComputerCollege() {
        departments = new Department[3];
        Adddepartment ("computer science and technology", "computer science and technology");
        Adddepartment ("Electronic Science and technology", "Electronic Science and technology");
        Adddepartment ("information and Communication Engineering", "information and Communication Engineering");
    }

    @Override
    public String getName() {
        Return "computer school";
    }

    @Override
    public void addDepartment(String name, String desc) {
        Department department = new Department(name, desc);
        departments[departmentNum] = department;
        departmentNum++;
    }

    @Override
    public Iterator createIterator() {
        return new ComputerCollegeIterator(departments);
    }
}


package com.charon.iterator;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @className: InfoCollege
 *@description: School of Information Engineering
 * @author: charon
 * @create: 2022-03-27 15:11
 */
public class InfoCollege implements College{

    List departments;

    public InfoCollege() {
        departments = new ArrayList<>(5);
        Adddepartment ("electrical engineering and automation", "electrical engineering and automation");
        Adddepartment ("Electronic Information Engineering", "Electronic Information Engineering");
        Adddepartment ("measurement and control technology and instrument", "measurement and control technology and instrument");
        Adddepartment ("Electronic Science and technology", "Electronic Science and technology");
        Adddepartment ("Internet of things project", "Internet of things project");
        Adddepartment ("Communication Engineering", "Communication Engineering");
    }

    @Override
    public String getName() {
        Return "School of Information Engineering";
    }

    @Override
    public void addDepartment(String name, String desc) {
        Department department = new Department(name, desc);
        departments.add(department);
    }

    @Override
    public Iterator createIterator() {
        return new InfoCollegeIterator(departments);
    }
}

Specific iterator roles:

package com.charon.iterator;

import java.util.Iterator;

/**
 * @className: ComputerCollegeIterator
 * @description:
 * @author: charon
 * @create: 2022-03-27 15:05
 */
public class ComputerCollegeIterator implements Iterator {

    /**
     *Storage of professional containers
     */
    Department[] departments;

    /**
     *Cursor, used to record the position of traversal
     */
    int cursor;

    public ComputerCollegeIterator(Department[] departments) {
        this.departments = departments;
    }

    @Override
    public boolean hasNext() {
        return cursor < departments.length && departments[cursor] != null;
    }

    @Override
    public Object next() {
        Department department = departments[cursor];
        cursor++;
        return department;
    }
}


package com.charon.iterator;

import java.util.Iterator;
import java.util.List;

/**
 * @className: InfoCollegeIterator
 * @description:
 * @author: charon
 * @create: 2022-03-27 15:16
 */
public class InfoCollegeIterator implements Iterator {

    List departments;
    /**
     *Array subscript
     */
    int index;

    public InfoCollegeIterator(List departments) {
        this.departments = departments;
    }

    @Override
    public boolean hasNext() {
        if (index >= departments.size() -1){
            return false;
        }
        index++;
        return true;
    }

    @Override
    public Object next() {
        return departments.get(index);
    }
}

other:

package com.charon.iterator;

/**
 * @className: Department
 *@description: Department
 * @author: charon
 * @create: 2022-03-27 14:58
 */
public class Department {

    private String name;

    private String desc;

    public Department(String name, String desc) {
        this.name = name;
        this.desc = desc;
    }

    /**
     * Gets the value of name
     *
     * @return the value of name
     */
    public String getName() {
        return name;
    }
}


package com.charon.iterator;

import java.util.Iterator;
import java.util.List;

/**
 * @className: OutputImpl
 * @description:
 * @author: charon
 * @create: 2022-03-27 15:19
 */
public class OutputImpl {

    List colleges;

    public OutputImpl(List colleges) {
        this.colleges = colleges;
    }

    /**
     *Traverse all colleges and output in turn
     */
    public void printCollege(){
        Iterator iterator = colleges.iterator();
        while (iterator.hasNext()){
            //Take out a college
            College college = iterator.next();
            System. out. Println ("College:" + college. Getname());
            printDepartment(college.createIterator());
        }
    }

    /**
     *Output discipline
     * @param iterator
     */
    private void printDepartment(Iterator iterator) {
        while (iterator.hasNext()){
            Department department = (Department) iterator.next();
            System. out. Println ("the Majors under the college are:" + department.getname());
        }
    }
}

Test:

package com.charon.iterator;

import java.util.ArrayList;
import java.util.List;

/**
 * @className: Client
 * @description:
 * @author: charon
 * @create: 2022-03-27 15:27
 */
public class Client {

    public static void main(String[] args) {
        //Create a college
        List colleges = new ArrayList<>(2);
        
        colleges.add(new ComputerCollege());
        colleges.add(new InfoCollege());

        OutputImpl output = new OutputImpl(colleges);
        output.printCollege();
    }
}

Print:
    College: Computer College
    The majors of the college are: Computer Science and technology
    The majors of the college are: Electronic Science and technology
    The majors of the college include: information and Communication Engineering
    College: Information Engineering College
    The majors of the college include: Electronic Information Engineering
    The majors of the college include: Measurement and control technology and instruments
    The majors of the college are: Electronic Science and technology
    The majors of the college include: Internet of things Engineering
    The majors of the college include: Communication Engineering

The advantages of the iterator pattern are as follows:

  1. Access the contents of an aggregate object without exposing its internal representation.
  2. The traversal task is left to the iterator, which simplifies the aggregation class.
  3. It supports traversal of an aggregate in different ways, and can even customize subclasses of iterators to support new traversal.
  4. It is convenient to add new aggregate classes and iterator classes without modifying the original code.
  5. It has good encapsulation and provides a unified interface for traversing different aggregation structures.

The disadvantages of the iterator pattern are as follows:

  1. The number of classes is increased, which increases the complexity of the system to a certain extent

Application scenarios of iterator pattern

Because aggregation is closely related to iterators, most languages provide iterator classes when implementing aggregation classes. Therefore, in most cases, it is enough to use iterators of existing aggregation classes in the language.

The iterator pattern is typically used in the following situations.

  1. When you need to provide multiple traversal methods for aggregate objects.
  2. When it is necessary to provide a unified interface for traversing different aggregation structures.
  3. When accessing the contents of an aggregate object without exposing the representation of its internal details.