A Pattern Example
The Design Patterns book covers only a tiny fraction of the common patterns. Here's a piece of code following a common pattern:
class Suit { private Suit() {} public static final HEARTS = new Suit(); public static final SPADES = new Suit(); public static final DIAMONDS = new Suit(); public static final CLUBS = new Suit(); }
What can we make of this class, based on patterns you've encountered before?
It has a limited number of instances.
It's not easy to make more of them.
It's easy to recognize this class as the common design pattern that I call Enumeration. It's similar to an enum in C, except that it's not equivalent to an integer. It's also similar to the Design Patterns Singleton interface, except that Singleton is designed to control access to an object with behavior (the example they provide is a print spooler), where these objects are important only because of their identity. It differs from Singleton in that Singleton requires exactly one instance. (Though the authors later say that Singleton permits "a variable number of instances"I believe the intention is that you may have more than one actual object for performance reasons, but they're intended to behave as if there is only a single object.)
The Enumeration pattern has these consequences:
If you have an instance of Suit, it must be one of these four objects.
Your code will always reference the objects by name, rather than by number, which makes it easier to read in the future.
Equality can be computed with == rather than .equals.
You can't add new suits without changing this class.
If you change this class, you need to check every place that Suit is used, to make sure that it doesn't depend on exactly these four instances.
You can't serialize the class easily, because the serialized form will not be equivalent to the object you read in.
Unlike C enums, these have no particular order.
It's relatively easy to extend this class into the design pattern I call an Ordered Enumeration:
class Suit implements Comparable { int n; private Suit(int n) { this.n = n; } public static final CLUBS = new Suit(1); public static final DIAMONDS = new Suit(2); public static final HEARTS = new Suit(3); public static final SPADES = new Suit(4); public int compareTo(Object o) { Suit s = (Suit) o; Return s.n - n; } }
The Ordered Enumeration pattern is like an Enumeration except that it implements the Comparable interface. Implementing it using integers is easy, as shown above. Although in general it's easier to use objects than integers, in this case the integers are all confined to the small piece of code above, which makes it easier to control their use.