UML Diagram
Figure 2 shows a UML diagram for the Iterator design pattern.

Figure 2: The UML diagram for the Iterator design pattern.
The diagram contains five classes:
- The Iterator interface declares methods
hasNext() and next().
- The concrete BaseballIterator class implements
hasNext() and next() for the data structure that stores baseball teams. (Likewise, the concrete FootballIterator class implements hasNext() and next() for the data structure that stores football teams.)
- The SportsTeams interface declares the
iterator() method. This method returns an Iterator objectan object with the appropriate hasNext() and next() methods. In the sports application, an "appropriate" method is one that works with either a List<Sports> object or a Sports[] array depending on the kind of team (baseball or football).
In the official GoF book's lingo, an interface such as SportsTeams is called an aggregate. An aggregate houses a group of objects, perhaps a Java collection of some kind (an ArrayList of baseball teams, for example). The iterator's job is to traverse the items that the aggregate stores. Now, back to the UML diagram in Figure 2:
- The concrete BaseballTeams class implements the
iterator() method for the data structure that stores baseball teams. (Likewise, the concrete FootballTeams class implements iterator() for the data structure that stores football teams.)
- The SportsApp class, the client application, uses aggregates and their iterators.
Implementing the Iterator Design Pattern
The following code contains an Iterator interface.
public interface Iterator<T> {
public boolean hasNext();
public T next();
}
In the Iterator interface, the next() method returns the next element in the data structure. The method's return type is T, a generic data type representing a BaseballTeam, a FootballTeam, or whatever. The hasNext() method returns either true (meaning "yes, the client can fetch another item from the aggregate") or false (meaning "no, the aggregate has no items worth fetching, because the client has already fetched all the aggregate's items").
The following code defines an aggregate interface. This particular aggregate contains teams.
public interface SportsTeams {
public void buildTeamList();
public Iterator<Sports> iterator();
}
In the aggregate interface, the new iterator() method returns a concrete instance of Iterator<Sports>. The return type isn't Iterator<Baseball> or Iterator<Football> because the code uses an interface and a base class.
The next order of business is to create concrete classes from the Iterator interface. The classes are in Listing 7 and 8.
In Listing 7 the BaseballIterator class has its own baseballListan instance of java.util.List<Sports>. In Listing 8, the FootballIterator class has its own footballList an instance of Sports[]. The use of instances is called composition. The alternative to composition is subclassing, in which BaseballIterator and FootballIterator are subclasses of Sports collections. For the Iterator pattern, composition is much better than subclassing. The BaseballIterator and FootballIterator classes use composition instead of subclassing.
Listing 4 and Listing 5 don't use the Iterator pattern. The following code snippets contain two different getTeamList() methods:
public List<Sports> getTeamList() // baseball
public Sports[] getTeamList() // football
Using the Iterator pattern, Listing 9 and 10 replace these getTeamList() methods with one iterator() method:
public Iterator<Sports> iterator() // both baseball and football
Listing 9 and 10 have the improved code using the uniform iterator() method.
In both Listing 9 and 10, the iterator() method returns an appropriate concrete iterator. In Listing 9 the method returns a BaseballIterator, and in 10 the method returns a FootballIterator. Using the Iterator pattern, the code buries the ugly details (baseball versus football? List versus array?) beneath the surface.
The original Sports, Baseball, and Football classes don't change at all when you adopt the Iterator Design pattern. But the client application (formerly Listing 6) changes a bit. The revised client application is in Listing 11.
When you execute the code in Listing 11 (the good code) you get the output of Figure 1the same as the output of Listing 6 (also known as "the bad code"). But when other developers read the code in Listing 11, they know nothing about the data structures lurking behind the scenes. Unlike Listing 6, the code of Listing 11 completely masks the implementations of BaseballTeams and FootballTeams. The masking is especially helpful when classes (like BaseballTeams and FootballTeams) have different underlying implementations.
So What? The Java API Already Has Iterators
The Java API has built-in iterators. So why should you bother coding the BaseballIterator and FootballIterator classes (Listing 7 and Listing 8)? The simplest answer is, not all aggregates have iterators. For example, in this article's sports application, the ArrayList (in BaseballTeams) has a built-in iterator, but the Sports array (in FootballTeams) does not. And what if you need more functionality? The Java API has a ListIterator (a bi-directional iterator with next() and previous() methods) but maybe your customized iterator skips records with missing values, hiding such records from your developers downstream. For many problems, the Iterator design pattern is both the most useful and the most elegant solution.
Resources
About the Authors
Barry Burd is a professor in the Department of Mathematics and Computer Science at Drew University in Madison, New Jersey. When he's not lecturing at Drew University, Dr. Burd leads training courses for professional programmers in business and industry. He has lectured at conferences in America, Europe, Australia, and Asia. He is the author of several articles and books, including "Java 2 For Dummies" and "Eclipse For Dummies," both published by Wiley.
Michael P. Redlich Michael Redlich is a currently a Senior Research Technician at a petrochemical research organization in New Jersey with extensive experience in developing custom web and scientific laboratory applications. Mike also has experience as a Technical Support Engineer for Ai-Logix, Inc. where he provided technical support and developed computer telephony applications for customers. He has been a member of the Amateur Computer Group of New Jersey (ACGNJ) since 1996, and currently serves on the ACGNJ Board of Directors as President of the club. Mike has also been facilitating the monthly ACGNJ Java Users Group since 2001. His technical experience includes computer security, relational database design and development, object-oriented design and analysis, design patterns, C/C++, Java, along with various markup and scripting languages in both the PC and UNIX environments. Mike has co-authored a number of articles with Barry Burd for JavaBoutique. He has also conducted seminars at Trenton Computer Festival (TCF) since 1998, TCF Professional Conference since 2006, and other venues including the New York Software Industry Association (NYSIA) Java Users Group, the Princeton Java Users Group, and the Capital District Java Developers Network. Mike is the co-chair of a local Science Ambassador program where he has conducted numerous science demonstrations and served as a Science Fair Judge for various elementary and middle schools in New Jersey. Mike holds a Bachelor of Science in Computer Science from Rutgers University.
New on the Java Boutique:
New Review:
Time Management Made Easy with the Quartz Enterprise Job Scheduler
Why not just use the Java timer API? This open source scheduling
API boasts simplicity, ease-of-integration, a well-rounded feature
set, and it's free!
New Applet:
Reverse Complement
Reverse Complement is a simple applet that converts DNA or RNA
sequences into three useful formats.
Elsewhere on internet.com:
WebDeveloper Java
Lots of Java information on webdeveloper.com
WDVL Java
Thorough Java resource at the Web Developer's Virtual Library.
ScriptSearch Java
Hundreds of free Java code files to download.
jGuru: Your View of the Java Universe
Customizable portal with online training, FAQs, regular news updates, and tutorials.
|