Definition
Provide a way to move through a list of collection or aggregated objects without knowing its internal representations.Intent
01- Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
- The C++ and Java standard library abstraction that makes it possible to decouple collection classes and algorithms.
- Promote to “full object status” the traversal of a collection.
- Polymorphic traversal
Problem
02Need to “abstract” the traversal of wildly different data structures so that algorithms can be defined that are capable of interfacing with each transparently.
Where to use & benefits
- Use a standard interface to represent data objects.
- Use s standard iterator built in each standard collection, like List, Sort, or Map.
- Need to distinguish variations in the traversal of an aggregate.
- Similar to Enumeration class, but more effective.
- Need to filter out some info from an aggregated collection.
- Related patterns include
- Composite, which supports recursive structures, whereas an iterator is often applied on it.
- Factory Method, which provides appropriate instances needed by an iterator subclasses.
- Memento, which is often used with an Iterator. The iterator stores the memento internally.
Motivation
One of the most common data structures in software development is what is generic called a collection. A collection is just a grouping of some objects. They can have the same type or they can be all cast to a base type like object. A collection can be a list, an array, a tree and the examples can continue.But what is more important is that a collection should provide a way to access its elements without exposing its internal structure. We should have a mechanism to traverse in the same way a list or an array. It doesn't matter how they are internally represented.
The idea of the iterator pattern is to take the responsibility of accessing and passing trough the objects of the collection and put it in the iterator object. The iterator object will maintain the state of the iteration, keeping track of the current item and having a way of identifying what elements are next to be iterated.
Intent
Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.The abstraction provided by the iterator pattern allows you to modify the collection implementation without making any changes outside of collection. It enables you to create a general purpose GUI component that will be able to iterate through any collection of the application.
Implementation
The Iterator pattern is one, which allows you to navigate through a collection of data using a common interface without knowing about the underlying implementation.
Iterator should be implemented as an interface. This allows the user to implement it anyway its easier for him/her to return data.
We use iterators quite frequently in everyday life. For example, remote control of TV. Any remote control we use, either at home/hotel or at a friend’s place, we just pick up the TV remote control and start pressing Up and Down or Forward and Back keys to iterate through the channels.
What sort of interface can Iterator be in case of Remote Controls?
/** * Iterator interface has method declarations for iterating through * TV channels. All remote controls implement Iterator. */ public interface Iterator { | ||
public Channel nextChannel(int currentChannel); public Channel prevChannel(int currentChannel); | ||
}// End of interface |
The channel iterator is common for all the remote controls. It’s like a specification implemented by all the remote control manufacturing companies.
/** * ChannelSurfer is a part of remote control which implements the Iterator * interface. This class overrides the nextChannel and prevChannel methods. */ public ChannelSurfer implements Iterator { | |||
/** * nextChannel – method which takes the current channel number * and returns the next channel. */ public Channel nextChannel (int currentChannel) { | |||
Channel channel = new Channel(currentChannel+1); return channel; | |||
} | |||
/** * prevChannel – method which takes the current channel number * and returns the previous channel. */ public Channel prevChannel (int currentChannel) { | |||
Channel channel = new Channel(currentChannel-1); return channel; | |||
} | |||
}// End of class |
/** * RemoteControl class is the actual remote control and it behaves and makes * use of ChannelSurfer. */ public class RemoteControl { | |||
private ChannelSurfer surfer; private Settings settings; public RemoteControl() { | |||
surfer = new ChannelSurfer(); settings = new Settings(); | |||
} | |||
/** * getProgram returns the program for that channel. * */ public getProgram(ChannelSurfer surfer) { | |||
return new Program(surfer.nextChannel()); | |||
} | |||
}// End of class |
We all know that every channel is associated to a program and it’s basically the program and not the channel number which a user wants to see. And so, the implementation which returns a program for channels surfed.
This tells us that we can apply some logic before returning the elements through iterator. We can set rules. The Iterator here, can also be programmed to return the ‘programs’ straight away rather than returning the channels.
The common Java iterator is Enumeration which has implicit
hasMoreElements()
and nextElement() methods.
The benefits of Iterator are about their strength to provide a common interface for iterating through collections without bothering about underlying implementation.
Iterator in Java: Before and after
Why read if you can watch?
Watch design patterns video tutorialBefore
01
The class
02SomeClassWithData
provides
access
to its internal data structure. Clients can
accidently or maliciously trash that data structure.
class SomeClassWithData
{
private TreeSet < Integer > m_data = new TreeSet < Integer > ();
public void add(int in)
{
m_data.add(in);
}
public Collection get_data()
{
return m_data;
}
}
class IteratorDemo
{
public static void main(String[] args)
{
SomeClassWithData some_object = new SomeClassWithData();
for (int i = 9; i > 0; --i)
some_object.add(i);
Collection data = some_object.get_data();
for (java.util.Iterator it = data.iterator(); it.hasNext();)
System.out.print(it.next() + " ");
System.out.println();
// Do we really want a client to be able to
// trash encapsulated state?
data.clear();
data = some_object.get_data();
System.out.println("size of data is " + data.size());
}
}
1 2 3 4 5 6 7 8 9
size of data is 0
After
03
Take traversal-of-a-collection functionality out
of the collection and promote it to “full object
status”. This simplifies the collection, allows
many traversals to be active simultaneously, and
decouples collection algorithms from collection
data structures.
04class SomeClassWithData
{
private TreeSet < Integer > m_data = new TreeSet < Integer > ();
public class Iterator
{
private SomeClassWithData m_collection;
private java.util.Iterator m_it;
private int m_current;
public Iterator(SomeClassWithData in)
{
m_collection = in;
}
public void first()
{
m_it = m_collection.m_data.iterator();
next();
}
public void next()
{
try
{
m_current = m_it.next();
}
catch (NoSuchElementException ex)
{
m_current = - 999;
}
}
public boolean is_done()
{
return m_current == - 999;
}
public int current_item()
{
return m_current;
}
}
public void add(int in)
{
m_data.add(in);
}
public Iterator create_iterator()
{
return new Iterator(this);
}
}
class IteratorDemo
{
public static void main(String[] args)
{
SomeClassWithData some_object = new SomeClassWithData();
for (int i = 9; i > 0; --i)
some_object.add(i);
// get_data() has been removed.
// Client has to use Iterator.
SomeClassWithData.Iterator it1 = some_object.create_iterator();
SomeClassWithData.Iterator it2 = some_object.create_iterator();
for (it1.first(); !it1.is_done(); it1.next())
System.out.print(it1.current_item() + " ");
System.out.println();
// Two simultaneous iterations
for (it1.first(), it2.first(); !it1.is_done(); it1.next(), it2.next())
System.out.print(it1.current_item() + " " + it2.current_item() + " ")
;
System.out.println();
}
}
1 2 3 4 5 6 7 8 9
1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9
No comments:
Post a Comment