Iterator/Composite Patterns

CSC-430

Phillip Wright

The Iterator Pattern

Provides a way to access the elements of an aggregate object sequentially without exposing its underlying representation.

AKA: Cursor

Iterator Interface

public interface Iterator {
  public abstract hasNext();
  public abstract next();
  public abstract remove();
}

Iterator

  • Encapsulates the concept of iteration
    • Simple loops
    • Multi dimensional loops
    • Tree traversals
    • Any other structures…
  • Hides implementation details
  • Provides for multiple types of traversals
  • Provides a uniform interface for different aggregate types

Implementation

  • Internal or external?
  • Should the iteration algorithm be defined in the iterator or aggregate?
  • How are concurrent modifications handled?

The Composite Pattern

Composes objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.

Composite

public interface Graphic{
  public abstract void draw();
  public abstract void add(Graphic g);
}

Composite II

public class Picture implements Graphic{
  final List<Graphic> graphics;
  
  public void draw(){
    for(final Graphic g : graphics){
      g.draw();
    }
  }

  public void add(final Graphic g){
    graphics.add(g);
  }
}

Composite III

public class Rectangle implements Graphic{
  // [...]
}
public class Line implements Graphic{
  // [...]
}
public class Text implements Graphic{
  // [...]
}

Composite Pattern

  • Provides a simple interface for recursive structures
  • Makes it easy to add new kinds of components

When to use

  • You want to represent part-whole hierarchies
  • You want clients to treat all objects in a complex structure uniformly

Warning

A composite type necessarily represents a union of interfaces. This means that only a subset of the interface might be valid at a given time. Accordingly, the type system becomes much less useful and runtime checks will be required.