In this post we discuss two patterns: the Iterator pattern and the Composite Pattern.
Iterator Pattern
Intro
Suppose you are merging two restaurants. Each has their own menus and implemented differently. Say one uses ArrayList
, another uses Array
. How would you iterate over the menus? We may of course do a type check and treat them differently. However, this will expose the internal representation and seems not so generic. Do we have a better approach? The Iterator Pattern comes to our rescue.
Instead of exposing the internal representation, we may define a method called createIterator()
that returns an Iterator
. In such manner, we could use the returned Iterator
interface hasNext()
, next()
.
Formal Definition
The Iterator Pattern provides a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
That is, the client should deal with two interfaces: the Aggregate
and the Iterator
. And the Aggregate
should have a method called createIterator
which returns an Iterator
.
Composite Pattern
Intro
Suppose now you are merging more restaurants, whose menus have submenus. Now we have recursive structure here. Instead of treating menu and menuItem separately, we may use Composite Pattern to treat them transparently/uniformly. We may define an interface MenuComponent
and let Menu
and MenuItem
implement that.
Formal Definition
The Composite Pattern allows you to compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.
What's more, since our Composite often contain many subcomponents, we may implement a createIterator()
method. This is the connection between Iterator Pattern and Composite Pattern.
Top comments (0)