It Era Tor
It Era Tor
Provide a way to access the elements of the aggregate object sequentially without exposing its underlying
representation. Aggregate object is an object that contains other objects for the purpose of grouping those
objects as a unit.It is also called a container or a collection.Examples are linkedList,Hashtable,ArrayList
etc.
Motivation
• Aggregate object such as a list should allow a way to traverse its elements without exposing its
internal structure.
• It should allow different traversal methods.
• It should allow multiple traversals to be in progress concurrently.
• But we really donot want to add all these methods to the interface for the aggregate.
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.
1
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.
*/
/**
* 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.
2
The benefits of Iterator are about their strength to provide a common interface for iterating through
collections without bothering about underlying implementation.
But why?
The iterator separates out the functionality of stepping through a group of items into its own class -
promoting one-class, one-responsibility design which gives the aggregate only one reason to change itself
instead of two. Separating iteration out encapsulates the functionality so that clients can expect
predictable results when reviewing a collection, which promotes polymorphism.
• Ruby
• .Net
//Java
public BookList() {
//constructor code
}
//Our booklist uses a hastable, which provides its own iterator method.
//a more generic collection may need its own iterator created, something
//like this:
public class BookShelfIterator implements Iterator {
BookShelf[] list;
int position = 0;
3
}
Iterator
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
4
• access contents of a collection without exposing its internal structure.
• support multiple simultaneous traversals of a collection.
• provide a uniform interface for traversing different collection.
Example 1: This exmple is using a collection of books and it uses an iterator to iterate through the
collection. The main actors are:
interface IIterator
{
public boolean hasNext();
public Object next();
}
interface IContainer
{
public IIterator createIterator();
}
And here is the code for concrete classes for iterator and collection. Please note that the concrete iterator
is an nested class. This way it can access all the members of the collection and it is encapsulated so other
classes can not access the BookIterator. All the classes are not aware of BookIterator they uses the
IIterator:
5
Specific problems and implementation
• Step one: the collection return a new iterator (using in our example the createIterator method).
Usually this step is not affected when it is used in multithreading environments because it returns
a new iterator object.
• Step two: The iterator is used for iterating through the objects. Since the iterators are different
objects this step is not a problematic one in multithreading environments.
It seems that the iterator does not raise special problems when a collection is used from different threads.
Of course here we are talking about an "seems". To reformulate the iterator does not raise special
problems when the collection used from different threads as long the collection is not changed.
• A new element is added to the collection (at the end). The iterator should be aware of the new
size of the collection and to iterate till the end.
• A new element is added to the collection before the current element. In this case all the iterators
of the collection should be aware of this.
The same actions should occur when an element is removed from the collection. The iterators should be
aware of the changes.
The main task when creating a multithreading iterator is to create a robust iterator (that allows insertions
and deletions without affection transversal). Then the blocks which are changing or accessing resources
changed by another thread have to be synchronized.
In languages like .net on java it's very easy to create external iterators. In our classical implementation an
external iterator is implemented. In the following example an external iterator is used:
// using iterators for a clloection of String objects:
// using in a for loop
for (Iterator it = options.iterator(); it.hasNext(); ) {
String name = (String)it.next();
System.out.println(name);
}
// using in a for-each loop (syntax available from java 1.5 and above)
for (Object item : options)
System.out.println(((String)item));
On the other side implementing and using internal iterators is really difficult. When an internal iterator is
used it means that the code is be run is delegated to the aggregate object. For example in languages that
offer support for this is easy to call internal iterators:
collection do: [:each | each doSomething] (Smalltalk)
The main idea is to pass the code to be executed to the collection. Then the collection will call internally
the doSomething method on each of the components. In C++ it's possible to send the doMethod method
6
as a pointer. In C# .NET or VB.NET it is possible to send the method as a delegate. In java the Functor
design pattern has to be used. The main idea is to create a base Interface with only one method
(doSomething). Then the method will be implemented in a class which implements the interface and the
class will be passed to the collection to iterate. For more details see the Functor design pattern.
The other option is to implement the traversal algorithm in the iterator. This option offers certain
advantages and some disadvantages. For example it is easier to implement different algorithms to reuse
the same iterators on different aggregates and to subclass the iterator in order to change its behavior. The
main disadvantage is that the iterator will have to access internal members of the aggregate. In Java
and .NET this can be done, without violating the encapsulation principle, by making the iterator an inner
class of the aggregate class.
Robust Iterators
- Can the aggregate be modified while a traversal is ongoing? An iterator that allows insertion and
deletions without affecting the traversal and without making a copy of the aggregate is called a robust
iterator. A robust iterator will make sure that when elements are added or removed from an aggregate
during iteration; elements are not accessed twice or ignored.
Lets' say we don't need a robust iterator. If the aggregate can not be modified (because the iteration is
started), it should be made explicitly, meaning that the client should be aware of it. We can just return a
false value what an element is added to the collection stating that the operation has failed, or we can
throw an exception.
An alternative solution is to add functions to change the aggregate in the iterator itself. For example we
can add the following methods to our iterator:
bool remove();
bool insertAfer();
bool insertBefore();
In the case when this solution is chosen the iterator handles the changes of the aggregator. In this case
the operation to change the iteration should be added to the iterator interface or base class not to the
implementation only, in order to have a general mechanism for the entire application.
Iterator Pattern
Definition
Provide a way to move through a list of collection or aggregated objects without knowing its internal
representations.
7
Example
import java.util.*;
interface Employee {
public abstract double earnings();
}
class Manager implements Employee {
private double weeklySalary;
private String name;
public Manager(String name, double s) {
this.name = name;
setWeeklySalary(s);
}
void setWeeklySalary(double s) {
if (s > 0) {
weeklySalary = s;
} else
weeklySalary = 0;
}
void setWagePerPiece(double w) {
if (w > 0)
wagePerPiece = w;
else
wagePerPiece = 0;
}
void setQuantity(int q) {
if ( q > 0)
quantity = q;
else
quantity = 0;
}
public String getName() {
return name;
}
public double earnings() {
return quantity * wagePerPiece;
}
8
public String toString() {
return "Piece worker: " + getName();
}
}
void setHourlyWage(double w) {
if (w > 0)
hourlyWage = w;
else
hourlyWage = 0;
}
void setHours(double h) {
if ( 0 <= h && h < 168)
hours = h;
else
hours = 0;
}
public String getName() {
return name;
}
public double earnings() {
return hourlyWage * hours;
}
public String toString() {
return "Hourly worker: " + getName();
}
}
9
totalSales = ts;
else
totalSales = 0;
}
public String getName() {
return name;
}
public double earnings() {
return salary + commission/100*totalSales;
}
public String toString() {
return "Commission worker:"
+ getName();
}
}
class EmployeeTest {
public static void main(String[] args) {
java.util.List list = new ArrayList();
list.add(new Manager("Bill", 800.00));
list.add(new CommissionWorker("Newt", 400.0, 3.75, 159.99));
list.add(new PieceWorker("Al", 2.5, 200));
list.add(new HourlyWorker("Babara", 13.75, 40));
list.add(new Manager("Peter", 1200.00));
list.add(new CommissionWorker("Margret", 600.0,5.5, 200.25));
list.add(new PieceWorker("Mark", 4.5, 333));
list.add(new HourlyWorker("William", 31.25, 50));
The above example also shows a dynamic binding feature which is popular in Object-Oriented realm.
If you want to pick up a specific object from the aggregated list, you may use the following code.
while(iterator.hasNext()) {
Employee em = (Employee)iterator.next();
if (em instanceof Manager) {
System.out.print(em + " earns $");
System.out.println(em. earnings());
}
}
The above list can also be replaced by an array and achieve the same result.
10