SeaJUG: Patterns WingDing Meeting Report
for
14 Oct 98
by
George Smith

Last night "we" (13 of us) met at Jason's place and reviewed two patterns:

    Iterator, &
    Template Method.

Before the meeting, I had thought that "Iterator" was sort of "worthless". However, the others convinced me that the flexibility facilitated by using an Iterator (with the standard interface) is the "right" way to go. I only wish I had been familiar with this 18 months ago...

Some thoughts on Iterator:

    1) The actual class implementing the Iterator "interface"
        should be an "inner class".
    2) The creation of an Iterator object should ALWAYS be done
        by a "factory" method on the "aggregate" object/class.
    3) The factory(ies) that create the Iterator objects should
        create all the "types" of Iterators (forward, backward)
        that visit ALL the elements, AND "types" that via special
        knowledge can "trim" the number of elements "visited"
        (such as skipping whole sections of a tree).
    4) If a "filtering" Iterator is going to filter based on
        Business Logic (Loan is less than X), it can be
        implemented by Iterator "nesting".
    5) Implementing "robust" Iterators is a "pain"!
Template Method:

I use this pattern a lot! We discussed how one could implement the same functionality without using inheritance by passing an object who's methods are called by the object that has the "fixed" logic. This was referred to as the "Strategy" pattern. The "problem" here was that when Template Method is normally used, the "small primitive methods" implemented do not "normally" rise to the level of abstraction that is normally granted to a "Strategy" approach.

Other thoughts on Template Method:

    1) Use it when you have two or more things that are "almost"
        the same.  Where you can isolate the differences to
        relatively primitive methods.
    2) When there is the "possibility" that one of the "things"
        will need to "totally" replace the "common" approach
        (override the common method).
    3) Often a static factory method in the abstract "common"
        class is used to create the "concrete" objects.
Response from: Alan Shalloway

Good points about the iterator. I like to think of the iterator in conceptual terms when setting up the architecture or requirements of a system. If we remember that an iterator's purpose is to allow us to go through a set of objects in any way (varying the order and the selection process) we can make our designs more flexible.

For example, a report that gives information on records in a database can be made flexible by having an iterator get the records. Then, if someone wants to select the records, they can do so by changing iterators. Sure, some selections can be done with SQL, but some can't -- an iterator allows for anything. By combining the iterator with a factory, as suggested, you can write components where the people writing code that uses the componets can supply their own iterators.

Iterators can also be useful with GUIs in that you can easily change the order or selection of records shown to users. This can be more easily accomplished if the iterator is used in confunction with the model-view-controller pattern, where iterators can be written in a general purpose fashion to be used with all of your files.