CPSC 233 W09-04-01

From AGg Wiki
Jump to: navigation, search

Adapter Design Pattern

The adapter design pattern, sometimes known as the wrapper design pattern, converts the interface of a class into another, expected, interface [1]. In other words, it allows a class, that has an incompatible interface, to be adapted for a client so that it has a compatible interface. This is done by means of an adapter class, that adapts an adaptee class to use the target interface that the client expects.

Some definitions from Design Patterns [1]:

Client

The client is a class that would like to make use of a target interface.

Target

The interface that the client expects to use when communicating with a class.

Adaptee

An existing class that provides some (if not all) of the functionality that we need. However, it does not conform to the target interface.

Adapter

A wrapper class, that conforms to the target interface, and adapts the adaptee to this interface.

There are a number of ways to build an adapter. In the object adapter approach, object composition is used. That is, we add an instance of the class which we wish to adapt to the adapter (wrapper) class. The wrapper class then forwards all relevant requests to the adaptee.

The following example, adapted from the Wikipedia article on the Adapter pattern should make this more clear [2]:

233 W09 T19 Adapter Pattern.gif

  • A class diagram for the above code.

Iterator Design Pattern

Iterators are a design pattern that abstract the task of navigating through an aggregate object. An aggregate object is something such as a linked list, or dynamic array (there are many more). The iterator design pattern is used to navigate an aggregate object in a generic way. If one had an iterator for a linked list, and an iterator for a dynamic array, the use of these iterators would be identical.

For the sake of simplicity, we will loosely refer to an aggregate object as a list. Commonly, an iterator has the following methods:

  • first() - sets the iterator to the start of the list
  • next() - moves the iterator forward, to the next element, in the list
  • isDone() - determines whether the iterator has encoutered the last object in the list
  • currentItem() - returns the current item in the list

We might use an Iterator in the following manner:

Iterator* iterator = myList->getIterator();
for( iterator->first(); ! iterator->isDone(); i->next() )
{
	cout << "currentItem: " << iterator->currentItem();
}

Iterators are fairly intuitive, however, there is more to the pattern. Gamma et el. define the following:

Client

The client is the class using the Aggregate object (list) and the Iterator belonging to the list.

Iterator

An abstract interface for accessing and traversing the elements in an Aggregate object.

Concrete Iterator

Simply a subclass of the Iterator (the abstract parent class), that provides a concrete implementation (instantiatable implementation).

Aggregate

An aggregate is an abstract class that defines the interface for creating an Iterator.

Concrete Aggregate

A concrete aggregate is just a subclass of an aggregate the provides an implementation for the abstract parent class (the Aggregate). Furthermore (and this is key), its createIterator method creates a Concrete Iterator.

233 W09 T19 Iterator Pattern.gif

  • A class diagram showing the Iterator Pattern as defined by Gamma et el.

STL Iterators

In C++ the Standard Template Library (STL) does not follow the iterator design pattern to the letter, rather, it keeps in mind the "spirit" of the pattern.

Consider the vector and list classes from the STL. The vector and list classes have no superclasses. The iterators are obtained from these classes by using the begin() and end() methods of the classes.

Furthermore, instead of the vector class defining an iterator especially for the vector class (subclassing iterator, and implementing a subclass tailored for the vector class), the class actually makes use of a generic iterator class. This iterator class is also used by all of the other containers in the STL. Things are actually a lot more complicated than this, but we have outlined a high level view of how things work. Below is a class diagram of STL vector, list and iterator:

An example using STL vector with an iterator is available here:

233 W09 T19 Stl vector.gif

  • A class diagram showing the basics of iterators as used with vectors and lists in the STL.

References