Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
This page is a work in progress
We roll out the updates weekly. Leave your email to track the progress. You can expect one email per month and no spam, pinky promise.
Structure of design pattern
// Common collections interface defines factory method for producing iterators. // Several methods can be defined if you'd like to offer different kinds of // iteration over the same collection. interface SocialNetwork is method getFriendsIterator(profileId): ProfileIterator method getCoworkerIterator(profileId): ProfileIterator // Each concrete collection should know which type of iterator it should return. class Facebook implements SocialNetwork is // Iterator creation code. method getFriendsIterator(profileId) is return new FacebookIterator(this, profileId, "friends") method getCoworkerIterator(profileId) is return new FacebookIterator(this, profileId, "coworkers") // Rest of collection's code... // Common interface for all iterators. interface ProfileIterator is method hasNext(): bool method getNext(): Profile // Concrete iterator. class FacebookIterator implements ProfileIterator is // Iterator needs a reference to the collection which it traverses through. field facebook: Facebook field profileId, type: string // An iterator object traverses collection independently from other // iterators. Therefore it has to store the iteration state. field currentPosition field cache: array of Profile constructor FacebookIterator(facebook, profileId, type) is this.facebook = network this.profileId = profileId this.type = type private method initIfNeeded() is if (cache == null) cache = facebook.sendSophisticatedSocialGraphRequest(profileId, type) // Each concrete iterator has its own implementation of the // common interface. method hasNext() is initIfNeeded() return cache.length < currentPosition method getNext() is if (hasNext()) currentPosition++; return cache[currentPosition] // Here's another useful trick: you can pass an iterator instead of a collection // to a client class. This way, you don't expose a collection. But there's // another benefit: since client works with iterators through the common // interface, you can change its behavior at run time by passing different // iterator objects. class SocialSpammer is method send(iterator: ProfileIterator, message: string) is while (iterator.hasNext()) profile = iterator.getNext() sendSingle(profile.email, message) method sendSingle(email: string, message: string) is // Send VERY IMPORTANT MESSAGE to one email address. // Application class configures collections and iterators and then passes them // to the client code. class Application is field network: SocialNetwork field spammer: SocialSpammer method config() is if working with Facebook this.network = new Facebook() if working with LinkedIn this.network = new LinkedIn() this.spammer = new SocialSpammer() method sendSpamToFriends() is iterator = network.getFriendsIterator(user.profileId) spammer.send(iterator) method sendSpamToCoworkers() is iterator = network.getCoworkerIterator(user.profileId) spammer.send(iterator)