Skip to content

The Abstract Factory Pattern

11 April 2009

Recently I came across a design problem where refactoring to the abstract factory pattern provided a really elegant solution. Of course, I will again talk about emergent design and evolution. Things start out really simple – as they always do – with a class which I will call the API class. The API class is actually a complex class which contains a bunch of other internal objects and handles execution. Think of it as the core of the application.

Another requirement is to initialize some parameters from command line arguments. The initial design was really simple:

initial

The Parser class parses the command line and creates an instance of Foo. This instance is then passed to the API class as a parameter. Really simple.

static void Main(string[] args)
{
    API api = new API();
    Parser parser = new Parser();


    parser.Parse(args);
    api.DoSomeStuff(parser.Foo);
}

Up to this point, things look great. The Parser class handles argument parsing and creates the required objects. The API class then uses these objects to perform the core operation.

Then, things started to get complicated. First, the API class got extended to perform a larger set of operations. Now I won’t go into the details of the class but suffice to say it’s not feasable to break apart the class into smaller ones. So we end up with the new class:

complexapi

The new API exposes more methods, each of these taking different parameters. We want to be able to call each one of these methods based on command line arguments. For example, if the application is called with dosomestuff /foovalue=5, we know we have to create the Foo object with the value 5 and call DoSomeStuff. If the application is called with dootherstuff /foovalue=5 /barvalue=10, we know we have to create the Foo object with value 5, Bar object with value 10 and call DoOtherStuff.

Changing the Parser class to accomodate the new API parameters, would leave us with a mamoth class:

bigparser

This is bad design. If we call the application with dosomestuff, the Bar and string attributes of the parser are never used. Same thing for the other modes. It’s obvious we need to split this class into smaller pieces. I came up with the following design:

parsers

This could seem a bit complex at first, but it makes perfect sense. The abstract base class Parser implements generic argument parsing logic. The BasicParser just looks at the first command line argument and, based on it, creates the appropriate StuffParser. So if the first command line argument is dosomestuff, it creates a SomeParser then delegates the rest of the parsing to it. If the first argument is dootherstuff, it creates an OtherParser and delegates to it. Each StuffParser maps to one of the API calls, meaning it creates the required objects for that call from the command line. As for the StuffParser class itself, it was added because, in practice, there are some common elements for parsing all modes, I just simplified thing a bit in the example.

As I said, I was content with the design of the parser classes. From the outside, parsing looked as easy as before:

...
BasicParser parser = new BasicParser();
parser.Parse(args);
...

The problem appeared when trying to retrieve the newly created parameters for passing them to the API. The BasicParser can return an instance of StuffParser, but how do we know which one? We can use

StuffParser stuffParser = parser.GetStuffParser();

but the StuffParser class doesn’t create the objects we are interesetd in for each execution mode – only the classes that derive from it do.

Reaching this point, I started to think which is the best way to solve this problem. My first thought was to add the API calls in the parser themselves. This would be the easiest way to go. Have Parser declare an abstract Execute method. Have BasicParser delegate the Execute call to the StuffParser and have each one of the derived parser make the appropriate API call. For example, SomeParser can call API.DoSomeStuff since it has the required Foo object. But I didn’t like this idea. I didn’t like it because it violated the Single Responsibility Principle, which states that every object should have a single responsiblity. The parser is parsing command line arguments. It is too much for it to also call API methods, handle possible exception etc. So this was not the way to go.

So I came up with another solution: I used downcasting.

API api = new API();
BasicParser parser = new BasicParser();

parser.Parse(args);

if (parser.GetStuffParser() is SomeParser)
{
    SomeParser someParser = parser.GetStuffParser() as SomeParser;
    api.DoSomeStuff(someParser.Foo);
}
else if (parser.GetStuffParser() is OtherParser)
{
    OtherParser otherParser = parser.GetStuffParser() as OtherParser;
    api.DoOtherStuff(otherParser.Foo, otherParser.Bar);
}
else if ...

So the parsers only do parsing now, and we determine which mode was called by checking the type of the StuffParser created. This worked fine but I hated the code. Downcasting is a code smell. When you have to downcast, as I did above, most probably the design is wrong. If an interface is provided – either as an actual interface or a base class – and you receive this interface from somewhere – another class, a method, a property etc. – you shouldn’t downcast. That’s exactly the reason the interface is provided, so you don’t care which actual implementation is used. So the code was smelly. I had to refactor. But how? I liked the simple interface of the parser, so I didn’t want to change that. I liked the fact that the parsers created required objects from command line arguments. I had to find a better way of linking API calls to the parsers. And here comes the Abstract Factory Pattern:

abstractfactory

The abstract StuffDoer class encapsulates an API instance and exposes an abstract DoStuff method which takes no parameters. Each one of the derived classes implements the method so it performs the appropriate API call. SomeStuffDoer calls API.DoSomeStuff. OtherStuffDoer calls API.DoOtherStuff etc. I also moved the parameters from the parser classes to the stuff-doing classes. Now the parser classes have the same, single responsibility – to parse the command line and create appropriate objects, the difference being that they setup a StuffDoer instance.

SomeParser for example will parse /foovalue=5, create a SomeStuffDoer object and set its Foo attribute to 5. Each StuffDoer wraps an API call. SomeStuffDoer.DoStuff() calls API.DoSomeStuff(param1). The DoStuff method now provides a common interface to all API calls.

We call the StuffParser the abstract factory, the classes deriving from it – the concrete factories, the StuffDoer class is called the abstract product and the classes deriving from it – the concrete products.

And the previously smelly code now looks like this:

BasicParser parser = new BasicParser();

parser.Parse(args);
parser.GetStuffDoer().DoStuff();

That’s it. The Single Responsibility Principle holds, the implementations of interfaces remain hidden, the code stops smelling.

From → code complete

Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: