Sunday, 10 June 2012

Factory Pattern

In this post I’ll be looking at the factory pattern. I’ll start off by looking at how the factory pattern is commonly used and then I’ll take a look at the strict GoF (Gang of Four) definition which is a little different and to be honest not as well known. The factory pattern is all about encapsulating object creation logic into a single object that can be used by other parts of your code.

I’ll start off with an example that describes a scenario where the factory pattern could be put to work. Imagine we have an application that takes data from multiple sources and converts that data into a common data standard. We’d probably use a data adapter of some sorts to convert the incoming data to our common data standard. To begin with were going to receive data in CSV format so our code for creating a data adapter object might look something like this.
DataAdapter csvAdapter = new CsvDataAdapter();
Imagine requirements change and we’re told that we also have to handle XML data from another source. So we set to work building an XML data adapter and then create that object as follows.
DataAdapter xmlAdapter = new XMLDataAdapter();
Because we’ve got two different types of data adapter we’ll need some sort of conditional logic in our application that decides which data adapter to use. This logic might look something like the following.
// default to XML data adapter
if (adapterType_i.equals("csv"))
{
     return new CsvDataAdapter();
}
else
{
     return new XmlDataAdapter();
}
It’s likely that we’ll have to decide which data adapter we need at a number of different points in our application.  Rather than duplicate this logic every time we need to create an adapter we’ll put this code into a method that it can be reused. It’s likely that in the future our application will need to support new data formats so this logic will need to be extended. To ensure our code is easier to maintain we need to encapsulate the parts that are likely to change the most. In this case that’s the object creation code so using the factory pattern to encapsulate this code away from the rest of our logic makes sense.

Creating the Factory
We’ll start by creating the actual factory class itself - the factory will simply encapsulate the logic we’ve already defined.
public class DataAdapterFactory
{
    protected String adapterType_i;

    public DataAdapterFactory(String adapterType_p)
    {
        adapterType_i = adapterType_p;
    }

    public DataAdapter createDataAdapter()
    {
        // default to XML data adapter
        if (adapterType_i.equals("csv"))
        {
             return new CsvDataAdapter();
        }
        else
        {
             return new XmlDataAdapter();
        }
    }
}
The factory objects constructor takes a single adapterType parameter which it uses to decide what type of DataAdapter to create and return to the client. You’ll notice that the return type of the createDataAdapter method is DataAdapter, even though the method can return either a CsvDataAdapter or an XmlDataAdapter object. The code is exhibits polymorphic behaviour as it allows calling code to use the adapters in the same way regardless of the actual implementation. For example, if a client is returned an XmlDataAdapter, it should be able to call the same functions on that object as if it were any other type of adapter.

In our case we’ll implement this polymorphic behaviour by ensuring that all objects returned by the factory extend our abstract DataAdapter class. Extending classes will be forced to implement the convertData method and by doing so provide a specific DataAdapter implementation.
public abstract class DataAdapter
{
    public DataAdapter()
    {

    }

    /* method template that extending classes are forced to 
       implement */
    public abstract String convertData(String inputData_p);
}

Creating the concrete adapter classes 
So what do the concrete adapter implementations look like? We’ll start off by defining the CsvDataAdapter as follows.
public class CsvDataAdapter extends DataAdapter
{
     public CsvDataAdapter()
     {

     }

     public String convertData(String inputData_p)
     {
          // some data adapter code could go here to convert CSV to common data standard
         return "csv data[" + inputData_p + "] " +  "converted to common data standard";
     }
}
This class extends abstract DataAdapter and overrides the mandatory convertData method. I’ll not be providing the csv transformation code but the class above should be sufficient to show you how a DataAdapter implementation class is structured.
public class XmlDataAdapter extends DataAdapter
{
    public XmlDataAdapter()
    {

    }

    public String convertData(String inputData_p)
    {
        // some data adapter code could go here to convert XML to common data standard
        return "XML data[" + inputData_p + "] " +  "converted to common data standard";
    }
}
The relationship between the abstract DataAdapter and its subclasses is shown below.


Testing our factory
Before we test our factory here is a summary of what we’ve created so far.
  • DataAdaptrerFactory class 
  • DataAdapter abstract class 
  • CsvDataAdapter concrete implementation class 
  • XmlDataAdapter concrete implementation class
Now let’s see the factory pattern in action with a simple test harness.
public class TestFactoryPattern
{
    public static void main (String[] args_p)
    {

        DataAdapterFactory adapterFactory;
        DataAdapter dataAdapter;
        String convertedData;

        adapterFactory = new DataAdapterFactory("csv");
        dataAdapter = adapterFactory.createDataAdapter();
        convertedData = dataAdapter.convertData("some, simple, csv, data");

        System.out.println(convertedData);

        adapterFactory = new DataAdapterFactory("xml");
        dataAdapter = adapterFactory.createDataAdapter();
        convertedData = dataAdapter.convertData("<TestData>data</TestData>");

        System.out.println(convertedData);
    }
}
On line 10 we create a new factory object passing in the adapter type. On line 11 we then use the factory’s createDataAdapter method to get a reference to a new CsvDataAdapter object. Note that this object is assigned to a DataAdapter variable - this is possible because CsvDataAdapter is derived from the base type DataAdapter. On line 12 we invoke the convertData method and see it print some csv specific output. Lines 16, 17 and 18 follow a similar pattern with a new factory object being used to create an XmlDataAdapter. Once again this object is assigned to its parent type (DataAdapter) and when we invoke its convertData method we’ll see some XML specific output.

This simple example shows how we can use a factory class to create a variety of different object types. We’ve encapsulated our object creation logic inside a dedicated class making it easier to maintain than if it were scattered throughout our (hypothetical) application.

GoF factory pattern
The pattern I described above is a recognised and commonly used form of the factory pattern. However the formal GoF definition of the factory pattern is slightly different and states.
‘The factory pattern should define an interface for creating an object, but let subclasses decide which classes to instantiate. Factory method lets a class defer instantiation to subclasses’.
 The GoF definition of the factory class allows greater flexibility by allowing you to define how factory methods should be structured but leave it up to the sub classer to implement the actual factory.

Creating an abstract factory
In order to allow subclasses to decide which class to instantiate we’ll need to define the factory as an abstract class. The abstract class is a specification for a factory and the actual implementation is the responsibility of the developer that extends it.

Our factory specification is defined with the abstract class below.
public abstract class AbstractDataAdapterFactory
{
    public AbstractDataAdapterFactory()
    {

    }

    /* our abstract method that subclassers will implement */
    public abstract DataAdapter createDataAdapter(String adapterType_p);
}

Creating a concrete factory
Now that we have our specification we need to create a factory implementation by extending the abstract class. Our factory implementation will look similar to the factory created earlier except that it will extend the specification defined by our abstract class. You’ll notice that the factory returns the same types that were returned by our earlier example. We could have created new DataAdapter implementations but for convenience we’ll stick with the ones we defined in our earlier example (CsvDataAdapter, XlDataAdapter).

Testing our GoF factory
Now let’s see the GoF factory pattern in action with a simple test harness. You’ll notice that this test harness is almost identical to the one used earlier, except that this time we create an instance of our DataAdapterFactoryImpl class that extends the AbstractDataAdapterFactory.
public class TestGoFFactoryPattern
{
    public static void main (String[] args_p)
    {

        AbstractDataAdapterFactory adapterFactory;
        DataAdapter dataAdapter;
        String convertedData;

        adapterFactory = new DataAdapterFactoryImpl();
        dataAdapter = adapterFactory.createDataAdapter("csv");
        convertedData = dataAdapter.convertData("some, simple, csv, data");

        System.out.println(convertedData);

        adapterFactory = new DataAdapterFactoryImpl();
        dataAdapter = adapterFactory.createDataAdapter("xml");
        convertedData = dataAdapter.convertData("<TestData>data</TestData>");

        System.out.println(convertedData);
    }
}
On line 10 we create a new factory implementation and assign it to an AbstractDataAdapterFactory reference. This differs from the first example because we can now potentially have a number of different types of factory, each of which could be assigned to a AbstractDataAdapterFactory reference. The rest of this test class is almost identical to the test class used in the first example.

Why use the GoF factory pattern?
At this point you may well be asking why would I use the GoF factory pattern instead of the more traditional version described in the first part of this post? In both examples we have a factory object that encapsulates object creation logic and return objects that extend a base type. Rather than have a single factory class instantiate all our objects (like our first example), the GoF version allows us to have one or more sub classes that handle object creation. This allows greater flexibility because the abstract factory can be easily extended to support new requirements rather than continually having to amend a single factory class.  The GoF factory pattern is worth considering when there are a number of developers extending your factory class and making substantial changes to the base implementation. In these circumstances you would be better off defining a specification for the factory (abstract class) and letting the developers who are overriding it take care of the implementation.

Saturday, 2 June 2012

Decorator Pattern

This is the first blog in a series that will focus on design patterns. I’ll be looking at some of the most popular design patterns in use today and  how they can  be used to improve the way you write code. I'll cover the key benefits of these patterns and use code examples to show you how they can be implemented. 

The decorator pattern attempts to address an important design principle, and that is to keep your code closed for modification but open for extension. The decorator pattern allows you to implement new logic with little or no change required to existing logic. This achieved by ensuring that new task specific logic is encapsulated by individual objects rather than being spread across your code. This encapsulation of task specific logic makes code much easier to maintain going forward. The decorator pattern allows you to use wrapper objects to extend existing code with new behaviour being delivered by augmenting new logic to existing code at runtime.
The following example describes a scenario where code is being repeatedly modified to satisfy new requirements. This is a scenario faced be developers every day and one which the decorator pattern aims to improve. The code below shows a very simple message processing utility. For the sake of this example we’ll imagine this message processor is consuming messages from a queue and processing them.
To start with our MessageHandler is required to append a message id to the incoming message. Note: I won’t be providing any implementation details of the specific tasks being performed (appending id’s, persisting to the database etc) as these code samples are here to describe common problems and how they can be solved with design patterns.
public class MessageHandler
{      
    public void processMessage()
    {
        // some code to append an id to message
    }
}
What if requirements change and suddenly we need the MessageHandler to write the incoming message to a log after it’s appended an id? One approach would be to update the existing MessageHandler class as shown below.
public class MessageHandler
{ 
     public void processMessage()
     {
        // some code to append an id to message
        // some more code to write message to log
     }
}
Now our message handler appends an id to the incoming message and writes it to a log. This works fine but we have our logic for both tasks bundled up in the same class. While this may be fine for trivial code (like our example) it can become a maintenance headache when dealing with a more verbose or complex code.
Imagine that suddenly the requirements change again and we need the MessageHandler to write the incoming message to a database. Once again we’ll have to modify our code to satisfy this new requirement as shown below.
public class MessageHandler
{     
     public void processMessage()
     {
        // some code to append an id to message
        // some more code to write message to logs
        // some more code to persist message in database
     }
}
This approach means that core code is modified every time a new requirement is implemented. This doesn't fit very well with the design principle we mentioned earlier,  keeping code closed for modification but open for extension.
The next example is going to show how the decorator pattern can be used to deliver the same functionality shown above but with more care taken to ensure that existing code can be extended without modification.
We’ll l start off with our standard MessageHandler object containing our core logic (appending an id to an incoming message).
public class MessageHandler
{
 public MessageHandler()
 {

 }

 /* core functionality implemented here */
 public void processMessage(String message_p)
 {
  // some code to append a message Id to message
  System.out.println("Appending Id 1234 to " + message_p + "...");
 }
}
Now we’ll create some decorator classes which will act as wrappers for the MessageHandler defined above. This means that variables holding a MessageHandler object should also be able to hold objects that wrap MessageHandler objects. An easy way to do this is to extend our wrapper (decorator) classes from the MessageHandler class.
/* abstract class extends core MessageHandler */
public abstract class MessageHandlerDecorator extends MessageHandler
{
 public abstract processMessage();
}
Because this class is abstract we cannot instantiate objects from it. Its purpose is to ensure that all wrappers (decorators) are consistent by forcing anyone who extends it to implement their own version of the processMessage method.
Next we’ll add new functionality to write the incoming message to a log after the id has been appended.  We’ll do this by creating a concrete wrapper class encapsulating our new logic. This wrapper object will invoke the processMessage method of the object that it is wrapping before running its own processMessage implementation. It’s this invocation of the wrapped object that allows us to dynamically augment new logic to an existing object at runtime.
/* LogMessageHanlder wrapper class contains our new logic - note
 * that it takes a MessageHandler as a constructor parameter */
public class LogMessageHandler extends MessageHandlerDecorator
{
 MessageHandler messageHandler_i;

 public LogMessageHandler(MessageHandler messageHandler_p)
 {
  messageHandler_i = messageHandler_p;
 }

 public void processMessage(String message_p)
 {
  // call handler passed in
  messageHandler_i.processMessage(message_p);

  // some code to write message to log
  System.out.println("Writing  " + message_p + " to log...");
 }
}
We’ll further extend the message handler functionality to persist incoming messages to the database.  We’ll do this by creating another concrete wrapper class. Again this wrapper will invoke the processMessage method of the object that it’s wrapping before running its own processMessage implementation. 
/* PersitenceMessageHandler wrapper class contains our new logic - note
 * that it takes a MessageHandler as a constructor parameter */
public class PersitenceMessageHandler extends MessageHandlerDecorator
{
 MessageHandler messageHandler_i;

 public PersitenceMessageHandler(MessageHandler messageHandler_p)
 {
  messageHandler_i = messageHandler_p;
 }

 public void processMessage(String message_p)
 {
  // call handler passed in
  messageHandler_i.processMessage(message_p);
  
  // some code to append a write message to log
  System.out.println("Persisting " + message_p + " in database...");
 }
}
We now have the following
  •  MessageHandler class - contains implementation of core functionality that we want to extend.
  • MessageHandlerDecorator - Ensures that all wrappers are consistent by forcing anyone who extends this class to implement their own version of the processMessage method.
  • LogMessageHandler - Wrapper class containing new functionality for logging message
  • PersistenceMessageHandler - Wrapper class containing new functionality for persisting message to the database
Next we’ll test our code and see the decorator pattern in action. 
public class TestMessageHandlers
{
 public static void main (String[] args_p)
 {
  String testMessage = "<TestMesssage>data</TestMessage>";

  /* configuration one */
MessageHandler messageHandler = new PersitenceMessageHandler(new LogMessageHandler(new MessageHandler()));
  messageHandler.processMessage(testMessage);
 }
}
When we invoke the processMessage method on MessageHandler it triggers the following sequence of events.
  1. PersistenceMessageHandler invokes the processMessage method of LogMessageHandler (which was passed in as an argument constructor)
  2. LogMessageHandler invokes the processMessage method of MessageHandlder (which was passed in as an argument constructor)
  3. The MessageHandler processMessage method runs and prints ‘Appending Id 1234 to <TestMesssage>data</TestMessage>...
  4. When the MessageHandler processMessage method returns LogMessageHandler runs and prints ‘Writing  <TestMesssage>data</TestMessage> to log...
  5. When the LogMessageHandler processMessage method returns PersistenceMessageHandler processMessage runs and prints ‘Persisting <TestMesssage>data</TestMessage> in database...
The diagram below shows how the message handlers are wrapped.

The output from this test program is as follows.

Appending Id 1234 to <TestMesssage>data</TestMessage>...
Writing  <TestMesssage>data</TestMessage> to log...
Persisting <TestMesssage>data</TestMessage> in database...

We were able to extend the original functionality provided by MessageHandler by decorating it with additional logic at runtime. This new logic was implemented without having to amend the original MessageHandler class. This is an example of how the decorator pattern allows us to keep our code closed for modification but open for extension.

The main benefits of the decorator pattern are
  • Greater separation of concerns as code is split into individual objects that address specific requirements.
  • Existing logic does not have to be modified. New functionality is delivered in separate objects which are augmented to existing logic at runtime. This reduces the likelihood of introducing regression issues into existing code.
  • Greater flexibility in the way in which we deliver functionality. For example, the objects can be decorated or wrapped in different sequences to deliver a different sequence of events. Our test class above could be easily changed as follows.
MessageHandler messageHandler2 = new LogMessageHandler(new PersitenceMessageHandler(new MessageHandler()));
messageHandler2.processMessage(testMessage);

This will result in the following output (note the ordering of the last 2 statements has changed).

                Appending Id 1234 to <TestMesssage>data</TestMessage>...
Persisting <TestMesssage>data</TestMessage> in database...
Writing  <TestMesssage>data</TestMessage> to log...

While the sample code in this blog is very simple indeed, it should be sufficient to demonstrate the mechanics of the decorator pattern and the benefits that it delivers.