Notes on Patterns

Recommended Book: In their seminal work on patterns, "Design Patterns: Elements of Reusable Object-Oriented Software", the Gang of Four (Gamma, Helm, Johnson, and Vlissides) divides patterns into three types, Creation, Structural, Behavioral.


Click to read reviews or buy Design Patterns: Elements of Reusable Object-Oriented Software Design Patterns: Elements of Reusable Object-Oriented Software
  1. Creation Patterns
    1. Abstract Factory

      An Abstract Factory is used to create families of objects. In their book the GoF mentions using an Abstract Factory to create either Motif (an ancient Unix Windowing system) or Windows widgets.

    2. Builder

      This pattern separates the building of a complex object from its representation so many different representations can be built with the same construction process.

    3. Factory

      This pattern lets a Factory class actually instantiate the correct type of subclass of the object.

    4. The Singleton

      This pattern uses a single instance of a class in a system. In Java, a good example of this is the Runtime object. It is never constructed by a user, just the reference is obtained with Runtime.getRuntime().

      I've used the Singleton pattern with a ConnectionPool class. The constructor looks like this:

      public class ConnectionPool {
        private static ConnectionPool connectionPool = null;
      //make it private so no one outside can call it 
      private ConnectionPool(String initFile) throws Exception
      {
      ...
      }
      
      public static ConnectionPool getConnectionPool() throws Exception
      {
          if(connectionPool == null) {
           synchronized (Class.forName("ConnectionPool")) {
              if(connectionPool == null) {
      	   connectionPool = new ConnectionPool("C:/InetPub/conf/site.prop");
              }
           }
          }
          return connectionPool;
      }
      

      A user of this class would grab a reference to an instance of the class with something like,

      try {
         ConnectionPool myConnectionPool = ConnectionPool.getConnectionPool();
      ...
      
    5. Prototype

      Give a creator a prototype of the object you wish to create and have it clone one for you.

    6. Null Object (not in the GoF book)

      Instead of littering your code with repeating code like:

      myObject = getObject();
      if(myObject != null) {
         myObject.print();
      }
      

      Create a do nothing instance of the object that is returned from "getObject()" that implements all the methods of the object, but does nothing. The code above is replaced with:

      myObject = getObject();
      myObject.print();
      

      Or even

      getObject().print();
      

      From Kevlin Henney's article in Java Report Dec 1999.

  2. Structural Patterns
    1. Adapter

      This changes the interface of an object into an interface a client is expecting.

    2. Bridge

      A Bridge pattern is a more flex case of object hierarchy. Instead of binding objects to an abstraction of the object hierarchy, we bind it to an interface that bridges to an object hierarchy.

    3. Composite

      Create objects so they can be a part of a tree structure, so the object can be an object or a tree of objects.

    4. Decorator Pattern:

      The decorator pattern adds design flexibility over subclassing by dynamically wrapping objects with similiarly typed objects with the same operations. So if you want to add a "fly()" method to a bird, instead of adding "fly()" to the bird object (since not all birds fly) you can create a new BirdDecorator object that contains a Bird object and implements all the Bird methods and adds a "fly()" method to the BirdDecorator container class.

    5. Facade

      When a few clients need to talk to many components of a subsystem, the Facade pattern simplifies this and exposes a minimal interface over the subsystem components and have all the clients interface with a restricted number of interface calls. The Facade object will only expose the needed functionality and map that functionality to the appropriate subsystem components.

    6. Flyweight

      When a large number of objects are needed that are intrinsically the same, but differ only on some external changable properties, the Flyweight pattern creates a single instance of the object and gives the responsibility of providing the changable aspects to the parent of the instance of the flyweight object.

    7. Proxy

      When accessing an object has constraints like the object is expensive to create, it's at a remote location, it needs protection, or some other hinderance to simply returning an object, the Proxy pattern returns a substitute for the actual object. The substitute acts like the object and ameliorates the constraints.

  3. Behavioral Patterns

    Examples coming...

Good Links for Patterns

  1. Patterns Home Page
  2. Model-View-Controller-Client Framework