Home  /  Questions  /  Question



85   96.4
Dec 13, 2010


Abstract Factory vs Factory Method

I believe I have a good understanding of the difference between Abstract Factory and Factory Method, but I'd like to see what others think.

When I say Abstract I am referring to DoFactory.GangOfFour.Abstract.Structural - Abstract Factory
When I say Factory I am referring to DoFactory.GangOfFour.Factory.Structural - Factory Method

First, both of these patters are are very close siblings of each other, more like faternal twins.  From what I see, Abstract can almost always be used in place of Factory.  Abstract typically implements Factory.  The difference is basically another level of abstraction at the Client end - Abstract implements this additional level of abstraction.

The Client in Abstract is AnimalWorld.  The Client in Factory is simply MainApp.

From within both of these Clients, the factory is implemented in these lines:

Factory:
documents[0] = new Resume();
documents[1] = new Report();

Abstract:
 _carnivore = factory.CreateCarnivore();
_herbivore = factory.CreateHerbivore();

The difference here is that in Factory, the Client (Main) is hard coded with the objects it will create.
In Abstract, the Client (AnimalWorld) is passed in the factory used to create the objects.

Simply another level of inderection implemented in Abstract.

This additional level of inderection will allow for the ability to change the types of objects that the Client uses without recompiling the code.  To state it another way:

Factory allows for the Client to use objects that dynamically create themselves - Resume and Report generate their own members.

Abstract allows for the Client to be passed in a dynamically created object that will then dynamically create additional objects for the Client.

All of this sounds very academic and the naming is very confusing.  I would have named the patterns as such:

Factory = Factory Method (GoF) = Factory Method (Mike)

Abstract = Abstract Factory (GoF) = Abstract Factory Method (Mike)

This would imply that Abstract Factory Method is simply an implementation of Factory Method, with an additional level of inderection - which is the real world case.

This reminds me of a quote I read a while back - "There is no problem in OOP that can not be solved through another level of inderection, except of course, too much inderection".

Speaking of real world, where would I decide to use one or the other?  I'll first point out the limitation of the Factory.  The lines:

documents[0] = new Resume();
documents[1] = new Report();


create the Resume and Report - those classes then create the proper Pages.  I see Resume and Report as the Factories.

Lets say the team that developes Resume and Report comes up with version 2.  In the Factory method the Client (Main) code would have to be updated and recompiled:

documents[0] = new Resume2();
documents[1] = new Report2();

This is a requirment of the OCP - we cant just update Resume and Report to handle version 2.

Now lets look at Abstract.  Here the client is AnimalWorld. 

ContinentFactory africa = new AfricaFactory();
AnimalWorld world = new AnimalWorld(africa);
world.RunFoodChain();

It is clear here what the factory is and that it is being passed to AnimalWorld (the Client).

Lets say the team that is developing Africa comes up with version 2.  The code is then cahnged to the following:

ContinentFactory africa = new AfricaFactory2();
AnimalWorld world = new AnimalWorld(africa);
world.RunFoodChain();


This keeps us from recompiling the Client (AnimalWorld).  Big deal, right?  We still have to recompile Main, so what's the difference?

If you look in the Object Orientedd Analysis and Design with Applicaiton book (chapter 3 - Case Study Weather Station) they overcome the requirement to recompile Main by passing in to Main on the command line the TypeOf Factory.  This allows them to dynamically generate either AfricaFactory() or AfricaFactory2() - so no recompile is necessary at all.  They use weather station stuff, I'm putting it into context by saying AfricaFactory......

Honestly, it almost seems they had to justify the reasons for Abstract Factory by coming up with this cool implementation of passing in on the commandline the factory to instantiate.  And as they point out, this was a very new feature of Java anyway.  There is a much better reason for using Abstract.

So where does Abstract come into play by todays standards?  In Unit Testing.  The reason in my opinion to use Abstract (almost always) is so that the Client can be passed in different Factories - either the live Production Factory, or a stub/mock from a unit testing framework.

After thinking about this a bit more, I realize that by using Factory + Dependency Injection (such as Ninject or Unity) you are accomplishing Abstract.  So if you spent hours looking at Factory and Abstract wondering what is the difference and where would you implement one or the other, stop - just get back to writing code, you are probably using these patterns already anyway.

I think DoFactory has done a great job with providing this framework and I highly recommend it.  I would however recommend that the framework first presents the user Factory, then Abstract.  Because the projects are simply orderd alphabetically, the user first learns Abstract then gets to Factory and (in my case) wonders what the real difference is. 

Mike




72   96.1
Dec 16, 2010
Nice thinking Mike.