Design Pattern: Iterator Pattern

Iterator: Provides a way to sequentially access the elements of an aggregate object without exposing the object's internal representation.


When to use iterator mode

When you need to access an aggregated object, and you need to traverse whatever those objects are, you should consider using the iterator pattern.

When you need to traverse the aggregate in multiple ways, you can consider using the iterator pattern to provide a unified interface for traversing different aggregate structures such as start, next, end, current item, etc.

The iterator pattern is to separate the traversal behavior of collection objects and abstract an iterator class to be responsible, so as not to expose the internal structure of the collection, but also allow external code to transparently access the data inside the collection

Specific code implementation:
Define the iterator role (Iterator)

public interface Iterator {
 
    public boolean hasNext();
     public Object next();
 }

Defining a Concrete Iterator

  
  public class ConcreteIterator implements Iterator {
      private List list = null;
      private int index;
  
     public ConcreteIterator(List list) {
         super();
         this.list = list;
     }
 
     @Override
     public boolean hasNext() {
         if (index >= list.getSize()) {
             return false;
         } else {
             return true;
         }
     }
 
     @Override
     public Object next() {
         Object object = list.get(index);
         index++;
         return object;
     }
 
 }

Defining container roles (Aggregate)

//Define the operations that can be performed on the collection
public interface List {
 
     public void add(Object obj);  
     public Object get(int index);
     public Iterator iterator();  
     public int getSize();
}

Define a specific container role (ConcreteAggregate)

public class ConcreteAggregate implements List{
  
      private Object[] list;
      private int size=0;
      private int index=0;
     public ConcreteAggregate(){
          index=0;
         size=0;
         list=new Object[100];
     }
     @Override
     public void add(Object obj) {
         list[index++]=obj;
         size++;
     }
 
     @Override
     public Iterator iterator() {
         
         return new ConcreteIterator(this);
     }
     @Override
     public Object get(int index) {
         
         return list[index];
     }
     @Override
     public int getSize() {
         
         return size;
    }
 
 }

code test

public class IteratorTest {
  
      /**
       * @param args
       */
      public static void main(String[] args) {
  
         List list=new ConcreteAggregate();
         list.add("a");
         list.add("b");
         list.add("c");
         list.add("d");
         Iterator it=list.iterator();
         while(it.hasNext()){
             System.out.println(it.next());
         }
     }

 }

迭代器模式的优缺点:

  迭代器模式的优点有:

  • 简化了遍历方式,对于对象集合的遍历,还是比较麻烦的,对于数组或者有序列表,我们尚可以通过游标来取得,但用户需要在对集合了解很清楚的前提下,自行遍历对象,但是对于hash表来说,用户遍历起来就比较麻烦了。而引入了迭代器方法后,用户用起来就简单的多了。
  • 可以提供多种遍历方式,比如说对有序列表,我们可以根据需要提供正序遍历,倒序遍历两种迭代器,用户用起来只需要得到我们实现好的迭代器,就可以方便的对集合进行遍历了。
  • 封装性良好,用户只需要得到迭代器就可以遍历,而对于遍历算法则不用去关心。

  迭代器模式的缺点:

  • 对于比较简单的遍历(像数组或者有序列表),使用迭代器方式遍历较为繁琐,大家可能都有感觉,像ArrayList,我们宁可愿意使用for循环和get方法来遍历集合。

     迭代器模式是与集合共生共死的,一般来说,我们只要实现一个集合,就需要同时提供这个集合的迭代器,就像java中的Collection,List、Set、Map等,这些集合都有自己的迭代器。假如我们要实现一个这样的新的容器,当然也需要引入迭代器模式,给我们的容器实现一个迭代器。



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325642566&siteId=291194637