When to use the abstract factory pattern?

Luke picture Luke · Dec 2, 2010 · Viewed 10.4k times · Source

I'm trying to succinctly describe when to use a factory, for both myself and my team. I ran across the following related questions, which helped somewhat:

Based on these links, and a bunch of other sources (listed at the bottom), I've come up with the following:

When to use the abstract factory pattern:

  • when you use an interface var or the 'new' operator
    • e.g. User user = new ConcreteUserImpl();
  • and the code you are writing should be testable / extensible at some point

Explanation:

  • interfaces by their very nature imply multiple implementations (good for unit testing)
  • interface vars imply OCP- and LSP-compliant code (support sub-classing)
  • use of the 'new' operator breaks OCP/DI, because highly-coupled classes are hard to test or change

"Do I create a factory for every object type? That seems excessive."

  • no, you can have one (or a few) factories that produce a lot of (usually related) object types
  • e.g. appFactory.createUser(); appFactory.createCatalog(); etc.

When NOT to use a factory:

  • the new object is very simple and unlikely to be sub-classed
    • e.g. List list = new ArrayList();
  • the new object is not interesting to test
    • has no dependencies
    • performs no relevant or long-running work
    • e.g. Logger log = new SimpleLogger();

References:


My question is: is my summary accurate, and does it make sense? Is there anything I've overlooked?

Thanks in advance.

Answer

Cameron Skinner picture Cameron Skinner · Dec 2, 2010

I'd also say don't use a factory when you have a particular implementation that you want. To continue the List example, I know that I want an ArrayList because I'm doing random access. I don't want to rely on a factory getting this right when I can do it myself.

Conversely, when I don't want to know about the concrete subclass then I can use a factory and let it worry about which object to actually instantiate.

I guess I'd suggest that you add a bullet to the "when to use the abstract factory pattern" that says "and you don't really care which concrete subclass you get", and the converse to "when not to use a factory".

EDIT: Be careful to avoid the general-purpose tool-building factory factory factory.