Types as Objects
Pattern

Problem

Objects are organized into types. For example: a film can be
typed according to its genre: comedy, drama, SciFi, etc; its rating: G, PG, R, X; or it's
quality: excellent, good, fair, poor, etc.

It's natural to identify the type of an object with its
class, but this can lead to unwieldy inheritance hierarchies or inheritance
hierarchies with multiple representations of the same object. This, in turn,
can lead to synchronization problems.

For example, we can introduce subclasses of Film for each of
the above types:

But where in this hierarchy might one find an object
representing a film like The Matrix?

Certainly there would be instances of this film in the SciFi, Excellent, and R classes.

Now suppose this diagram represents a database used by an
online event calendar for San
Francisco. Suppose each film has attributes indicating
when and where it is showing in San
Francisco. One of the theaters decides to change the
time it will show the movie. The database administrator must update the show
time attribute of three objects representing this movie. Failure to update all
three will lead to a synchronization error. The database will be inconsistent.
People looking for the show time will get different answers depending on if
they are looking by genre, quality, or rating.

We could attempt to fix this problem with the following
design:

Now The Matrix is
represented by a single object, whichis an instance of SciFiRExcellent.

But this hierarchy is unwieldy. If there are three genres,
four ratings, and five qualities, then there will be a total of:

1 + 3 + 3 * 4 + 3 * 4 * 5 = 76 classes

Adding a fourth genre, Romance for example, will force us to
add 25 more classes!

Solution

If the type of an object is only used as a classification
scheme, if a difference in type doesn't imply a difference in attributes or
behavior, then consider representing the type of an object by another object.

Here's the general pattern:

A more interesting version of the pattern allows types to be
instances:

Implementation

With this in mind, we sketch generic implementations of
Instance and InstanceType below:

In the Video Rental domain there are two opportunities to
use the Types as Objects Pattern:

Advantages of type
objects

We can solve the problem of multiple representations of the
same film and unwieldy inheritance hierarchies by associating with each film
object three different type objects:

In this example we are using enumeration classes (classes
with a small fixed number of instances) as our types.

Adding a new genre, Romance, say, only involves creating a
new instance of the Genre class. This can be done at runtime, without changing
the design.

Disadvantages of
types as objects

Suppose that in addition to altitude and air speed, military
planes had a payload attribute (i.e., how many bombs can it carry). If types
are objects, then we can simply add payload to the attribute list for military
planes:

But if we use type tags, then here's what a typical military
plane looks like:

Where are we supposed to put payload?

Suppose also that the implementation of the takeoff
operation depends on the type of airplane. If types are objects, then we will
need a multi-way conditional to implement takeoff:

Object-oriented programmers dislike this style of coding
because it centralizes intelligence. It's better to distribute intelligence by
allowing each subclass of Airplane to redefine the takeoff method.

The Dynamic Object
Model (Property Lists)

We can overcome some of the disadvantages of the Types as
Object Pattern by associating property lists with our Instance and InstanceType classes. Here's the design: