Wednesday, December 26, 2012

Iterator Pattern and Java

Hello all, in this post we'll be checking on the Iterator Pattern. A design pattern that I know many of you have already used, but maybe you didn't realize it was pattern or didn't know its great value. According to the book Head First Design

The Iterator  Pattern provides a way to access the elements of an aggregate object sequentially without exposing its underlaying representation.

Whaaaaat? Well, it says that no matter what data structure (arrays, lists, hashtables,etc.) you are using, you can always traverse it in the same way if you implement this pattern. It gives you a uniform way of accessing the elements of your data structures (aggregates), but you don't have to know what kind of data structure you are traversing... nice!
Also, it sets the responsibility of iteration on the Iterator object not on your data structure, which simplifies the coding in your data structure.

Let's check the classic class diagram for the Iterator pattern:


The actual class diagram for the Iterator Pattern has a few changes, specially in the Iterator class (interface), where we now have different methods as we'll see in a minute, but first, lets review each of the previous classes (or interfaces):

  • Aggregate: This is the base class (or interface) of our data structures, you can think of it as the java.util.Collection interface, which defines a lot of methods for the collection classes.
  • ConcreteAggregate: This is the concrete data structure that we'll be iterating, for example, java.util.ArrayList, java.util.Vector, etc.
  • Iterator: Base class (or interface) for iterators. You can find one in Java at java.util.Iterator. You can notice that the Java version has different methods that we'll be discussing later in this post. Here you define de methods you need in order to traverse the data structures.
  • ConcreteIterator: As you want to traverse different data structures you need different iterators. So a concreteIterator is an Iterator for the data structure you want to traverse.  

Now, let's take a look at the Java implementation of the Iterator Pattern. The following diagram was generated using Architexa's Free Tool for Understanding Code and it shows the relations between some classes of the Java Collections Framework where we can see a structure similar to the classic class diagram:


The above diagram shows only one implementation of the pattern in Java, there are a lot more, but they always use the java.util.Iterator interface; this is the interface you should use in your implementations of the Iterator Pattern when coding in Java. Let's compare both diagrams:


Classic Diagram
ConcreteIterator

Notice that the methods of the Iterator object in the Java example are different from the methods in the classic class diagram:
  • There is no +First() method. If you need to go to the first element, you have to instance a new iterator.
  • The +IsDone() method has been renamed to +hasNext().
  • The +Next() and +CurrentItem() has been merged into +next().
  • The +remove() method has been added.

So, if you ever have to work with different data structures and need a uniform way to traverse them and/or access their items, think about the Iterator Pattern:

//... in a class
  /**
   * Traverse a list, hashtable, vector, etc. what ever that implements
   * the Iterator Pattern
   */
  public void traverse(Iterator iter)
  {
     while(iter.hasNext())
     {
 System.out.println(iter.next());
     }
  }

Of course, you will always have to create the ConcreteIterator class for your data structure, but if you are using classes from the Java Collections Framework, it's already done.

One last thing, remember the most important OO Principle of all: Always use the simplest solution that meets your needs, even if it doesn't include a pattern.


See ya!


References:

Freeman Eric and Freeman Elisabeth and Sierra Kathy and Bates Bert (2004). Head First Design Patterns. United States of America: O'Reilly Media, Inc.

No comments:

Post a Comment