Skip to main content

The GoF Hot Spots - Factory Method vs Abstract Factory

As part of my "GoF Design Patterns - The Hot Spots" posts series, this post is focused on two Creational Design Patterns: Factory Method and Abstract Factory.

We will dig into the original GoF Design Patterns (aka: DP) description trying to figure out the real Hot Spots (aka: specific particular parts that differentiating them from each other) of these two DPs and the relationship between them.

In order to maximize the clarity of this article, I used two conventions:
  • Phrases inside [square brackets] are meant to help understanding GoF definitions
  • Italic sentences are GoF's book citations

Factory Method

GoF Definition:

" [1] Define an interface for creating an object, [2] but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses."

GoF Description & Hot Pots:

"Consider a framework for applications that can present [handle] multiple documents to the user. Two key abstractions in this framework are the classes Application and Document.

Both classes are abstract, and clients have to subclass them to realize their application-specific implementations.
To create a drawing application, for example, we define the classes DrawingApplication and DrawingDocument.
The Application class is responsible for managing Documents and will create them as required—when the user selects Open or New from a menu, for example."


The Factory Method DP is useful when we have a need to handle some objects diversely, depending on some external state. In the GoF sample the 'state' is the Application type, meaning that every different type of Application must have the same actions methods (as described in the interface or abstract class they implement) but letting each specific Application subclass implement those methods as best for it's needs.
The framework needs to support actions like: Update, Delete,Print, Validate etc' and obviously also a Create method aka Factory Method.

It is important to note that subclassing in order to implement differently methods is a well known design regardless of Factory Method implementation. From the point of view of this post, the only interesting part of the following sample is our Factory Method, Create().

Exactly like all other methods also our Create method must be overridden by every concrete Application class (creator) in order to instantiate the appropriate Document type (product) to handle. By doing so we meat both DP goals:

  1. We defined an interface for creating objects via the Application interface, thus hiding the concrete specific type from the client
  2. Letting subclasses decide the concrete appropriate product to handle



The Framework's clients needs to instantiate the correct Document handler (Application class), internally each of Application subclass creates the appropriate Document object represented by a common interface.

Participants
  • Product(Document)
    • Defines the interface of objects the factory method creates
  • ConcreteProduct(MyDocument)
    • Implements the Product interface
  • Creator(Application)
    • Declares the factory method, which returns an object of type Product. Creator may also define a default implementation of the factory method that returns a default ConcreteProduct object
    • May call the factory method to create a Product object
  • ConcreteCreator(MyApplication)
    • Overrides the factory method to return an instance of a ConcreteProduct

Steal-Thread Implantation

The following is a clean implementation that highlights the DP Hot Spots (see full implementation in this site).
using System;
 
namespace DoFactory.GangOfFour.Factory.Structural
{
  /// 
  /// MainApp startup class for Structural
  /// Factory Method Design Pattern.
  /// 
  class MainApp
  {
    /// 
    /// Entry point into console application.
    /// 
    static void Main()
    {
      // An array of creators
      Creator[] creators = new Creator[2];
 
      creators[0] = new ConcreteCreatorA();
      creators[1] = new ConcreteCreatorB();
 
      // Iterate over creators and create products
      foreach (Creator creator in creators)
      {
        Product product = creator.FactoryMethod();
        Console.WriteLine("Created {0}",
          product.GetType().Name);
      }
 
      // Wait for user
      Console.ReadKey();
    }
  }
 
  /// 
  /// The 'Product' abstract class
  /// 
  abstract class Product
  {
  }
 
  /// 
  /// A 'ConcreteProduct' class
  /// 
  class ConcreteProductA : Product
  {
  }
 
  /// 
  /// A 'ConcreteProduct' class
  /// 
  class ConcreteProductB : Product
  {
  }
 
  /// 
  /// The 'Creator' abstract class
  /// 
  abstract class Creator
  {
    public abstract Product FactoryMethod();
  }
 
  /// 
  /// A 'ConcreteCreator' class
  /// 
  class ConcreteCreatorA : Creator
  {
    public override Product FactoryMethod()
    {
      return new ConcreteProductA();
    }
  }
 
  /// 
  /// A 'ConcreteCreator' class
  /// 
  class ConcreteCreatorB : Creator
  {
    public override Product FactoryMethod()
    {
      return new ConcreteProductB();
    }
  }
}

Output
Created ConcreteProductA Created ConcreteProductB

Abstract Factory

GoF Definition:

"Provide an interface for creating families of related or dependent objects without specifying their concrete classes"

GoF Description & Hot Spots:

"Consider a user interface toolkit that supports multiple look-and-feel standards, such as Motif and Presentation Manager. Different look-and-feels define different appearances and behaviors for user interface "widgets" like scroll bars, windows, and buttons. To be portable across look-and-feel standards, an application should not hard-code its widgets for a particular look and feel. Instantiating look-and-feel-specific classes of widgets throughout the application makes it hard to change the look and feel later.
We can solve this problem by defining an abstract WidgetFactory class that declares an interface for creating each basic kind of widget. There's also an abstract class for each kind of widget, and concrete subclasses implement widgets for specific look-and-feel standards. WidgetFactory's interface has an operation that returns a new widget object for each abstract widget class. Clients call these operations to obtain widget instances, but clients aren't aware of the concrete classes they're using. Thus clients stay independent of the prevailing look and feel."


The design issues that Abstract Factory is meant to solve are different from that of the Factory Method:

  1. Create a group of related objects
  2. Expose a stable unified public API to clients without specifying their concrete classes types



"A WidgetFactory also enforces dependencies between the concrete widget classes. A Motif scroll bar should be used with a Motif button and a Motif text editor, and that constraint is enforced automatically as a consequence of using a MotifWidgetFactory."

Exactly like Factory Method we have two independent hierarchies, the Creator (WidgetFactory) and the products (Window and ScrollBar) each concrete factory decide which related groups of products to instantiate.

This solution meets our main goal, because the WidgetFactory expose an interface to create groups of logically related products that hides the concretes products (widgets) types, the client knows only about the products and factory interfaces.

Participants

  • AbstractFactory (WidgetFactory)
    • Declares an interface for operations that create abstract product objects
  • ConcreteFactory (MotifWidgetFactory, PMWidgetFactory)
    • Implements the operations to create concrete product [group of] objects
  • AbstractProduct (Window, ScrollBar)
    • Declares an interface for a type of product object
  • ConcreteProduct (MotifWindow, MotifScrollBar)
    • Defines a product object to be created by the corresponding concrete factory
    • Implements the AbstractProduct interface
  • Client
    • Uses only interfaces declared by AbstractFactory and AbstractProduct classes

Steal-Thread Implantation

The following is a clean implementation that highlights the DP Hot Spots (see full implementation in this site).
using System;
 
namespace DoFactory.GangOfFour.Abstract.Structural
{
  /// 
  /// MainApp startup class for Structural
  /// Abstract Factory Design Pattern.
  /// 
  class MainApp
  {
    /// 
    /// Entry point into console application.
    /// 
    public static void Main()
    {
      // Abstract factory #1
      AbstractFactory factory1 = new ConcreteFactory1();
      Client client1 = new Client(factory1);
      client1.Run();
 
      // Abstract factory #2
      AbstractFactory factory2 = new ConcreteFactory2();
      Client client2 = new Client(factory2);
      client2.Run();
 
      // Wait for user input
      Console.ReadKey();
    }
  }
 
  /// 
  /// The 'AbstractFactory' abstract class
  /// 
  abstract class AbstractFactory
  {
    public abstract AbstractProductA CreateProductA();
    public abstract AbstractProductB CreateProductB();
  }
 
 
  /// 
  /// The 'ConcreteFactory1' class
  /// 
  class ConcreteFactory1 : AbstractFactory
  {
    public override AbstractProductA CreateProductA()
    {
      return new ProductA1();
    }
    public override AbstractProductB CreateProductB()
    {
      return new ProductB1();
    }
  }
 
  /// 
  /// The 'ConcreteFactory2' class
  /// 
  class ConcreteFactory2 : AbstractFactory
  {
    public override AbstractProductA CreateProductA()
    {
      return new ProductA2();
    }
    public override AbstractProductB CreateProductB()
    {
      return new ProductB2();
    }
  }
 
  /// 
  /// The 'AbstractProductA' abstract class
  /// 
  abstract class AbstractProductA
  {
  }
 
  /// 
  /// The 'AbstractProductB' abstract class
  /// 
  abstract class AbstractProductB
  {
    public abstract void Interact(AbstractProductA a);
  }
 
 
  /// 
  /// The 'ProductA1' class
  /// 
  class ProductA1 : AbstractProductA
  {
  }
 
  /// 
  /// The 'ProductB1' class
  /// 
  class ProductB1 : AbstractProductB
  {
    public override void Interact(AbstractProductA a)
    {
      Console.WriteLine(this.GetType().Name +
        " interacts with " + a.GetType().Name);
    }
  }
 
  /// 
  /// The 'ProductA2' class
  /// 
  class ProductA2 : AbstractProductA
  {
  }
 
  /// 
  /// The 'ProductB2' class
  /// 
  class ProductB2 : AbstractProductB
  {
    public override void Interact(AbstractProductA a)
    {
      Console.WriteLine(this.GetType().Name +
        " interacts with " + a.GetType().Name);
    }
  }
 
  /// 
  /// The 'Client' class. Interaction environment for the products.
  /// 
  class Client
  {
    private AbstractProductA _abstractProductA;
    private AbstractProductB _abstractProductB;
 
    // Constructor
    public Client(AbstractFactory factory)
    {
      _abstractProductB = factory.CreateProductB();
      _abstractProductA = factory.CreateProductA();
    }
 
    public void Run()
    {
      _abstractProductB.Interact(_abstractProductA);
    }
  }
}

Output
ProductB1 interacts with ProductA1 ProductB2 interacts with ProductA2

NOTE: This implementation introduces the Client class. This class is used for code reuse purposes only, it's not an essential part of this DP. From Abstract Factory point of view the Main method could have run the same instructions without the need of this class.

Misconceptions & Hot Spots

A common misconception is caused due the fact that one possible implementation of the Factory Method mentioned by the GoF is the: 'Parameterized Factory Methods':

"Another variation on the pattern lets the factory method create multiple kinds of products. The factory method takes a parameter that identifies the kind of object to create. All objects the factory method creates will share the Product interface. In the Document example, Application might support different kinds of Documents. You pass CreateDocument an extra parameter to specify the kind of document to create."

This DP variation is useful in scenarios where every concrete creator (Application subclass) has a range of various different type to instantiate based on a given external parameter (state).

For example, suppose that in the Factory Method GoF sample discussed above the concrete MyApplication creator is extended to support different types of products based on the current day of the week.

Instead of creating other six Application subclasses, one for each day of the week (MyApplicationSunday, MyApplicationMonday etc') only for letting them decide the correct product to peak up, we end up with unnecessary replication of code. Instead we can modify our Factory Method implementation to accept a 'state' parameter that determine the specific concrete product to instantiate from the given range of products.

Lets' take the DoFactory.com implementation and modify it to meet the 'Parameterized Factory Method' requirements:
using System;
 
namespace DoFactory.GangOfFour.Factory.Structural
{
  /// 
  /// MainApp startup class for Structural
  /// Factory Method Design Pattern.
  /// 
  class MainApp
  {
    /// 
    /// Entry point into console application.
    /// 
    static void Main()
    {
      // Same Implementation as in the previous sample...
    }
  }
 
  /// 
  /// The 'Product' abstract class
  /// 
  abstract class Product
  {
  }
 
  /// 
  /// A1 'ConcreteProduct' class
  /// 
  class ConcreteProductA1 : Product
  {
  }
 
  /// 
  /// B1 'ConcreteProduct' class
  /// 
  class ConcreteProductB1 : Product
  {
  }

/// 
  /// A2 'ConcreteProduct' class
  /// 
  class ConcreteProductA2 : Product
  {
  }
 
  /// 
  /// B2 'ConcreteProduct' class
  /// 
  class ConcreteProductB2 : Product
  {
  }
 
  /// 
  /// The 'Creator' abstract class
  /// 
  abstract class Creator
  {
    public abstract Product FactoryMethod(String state);
  }
 
  /// 
  /// A 'ConcreteCreator' class
  /// 
  class ConcreteCreatorA : Creator
  {
    public override Product FactoryMethod(string state)
        {
            switch (state)
            {
                case "A":
                    return new ConcreteProductA1();
                case "B":
                    return new ConcreteProductB1();
            }
        }
  }
 
  /// 
  /// A 'ConcreteCreator' class
  /// 
  class ConcreteCreatorB : Creator
  {
   
         public override Product FactoryMethod( string state)
        {
            switch (state)
            {
                case "C" :
                    return new ConcreteProductA2();
                case "D" :
                    return new ConcreteProductB2();
            }
        }
    
  }
}

Although the above is a valid implementation it's important to understand that this only a specific Factory Method implementation.

Secondly, as time passed, developers embraced the way 'Parameterized Factory Method' implementation solved the instantiation of a specific instant among a range of objects, and at the same time completely ignored one important aspect of this DP: "...but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses"

A 'Parameterized Factory Method' implementation must be implemented in conjunction with a subclassing hierarchy. Implementations that consist of a static Create method that internally instantiate the correct object based on some parameter can not be called Factory Method design pattern.
 //* Maybe a nice solution, but nothing to do with factory Method
        static public Product CreateInstant( string state)
        {
            switch (state)
            {
                case "A":
                    return new ConcreteProductA();
                case "B":
                    return new ConcreteProductB();
            }
        }

Relationship

After reading this long post we should now understand that Factory Method and Abstract Factory DPs have some common concepts:

  1. As explained by the GoF a parameterized approach can be used also for Abstract Factory implementation
  2. Both DPs are implemented via two abstract hierarchies: Creator and Product
  3. Both of them are designed to abstract out the instantiation of a specific Product by hiding the logic creation and the final concrete type from clients


But from my point of view the real relationship between this two DP is that the most popular way to implement the Abstract Factory DP is via several Factory Methods, one for each product of the related group.

I will highlight my last phrase by evaluating again the this Abstract Factory implementation:
  .
  .
  class ConcreteFactory2 : AbstractFactory
  {
    public override AbstractProductA CreateProductA() //* Factory Method
    {
      return new ProductA2();
    }
    public override AbstractProductB CreateProductB() //* Factory Method
    {
      return new ProductB2();
    }
  }
  .
  .

Comments

The Best

Closures in C# vs JavaScript -
Same But Different

Closure in a Nutshell Closures are a Software phenomenon which exist in several languages, in which methods declared inside other methods (nested methods), capture variables declared inside the outer methods. This behavior makes captured variables available even after the outer method's scope has vanished.

The following pseudo-code demonstrates the simplest sample:
Main() //* Program starts from here { Closures(); } AgeCalculator() { int myAge = 30; return() => { //* Returns the correct answer although AgeCalculator method Scope should have ordinarily disappear return myAge++; }; } Closures() { Func ageCalculator = AgeCalculator(); //* At this point AgeCalculator scopeid cleared, but the captured values keeps to live Log(ageCalculator()); //* Result: 30 Log(ageCalculator()); //* Result: 31 } JavaScript and C# are two languages that support…

Formatting Data with IFormatProvider & ICustomFormatter

This post provides an internal overview of IFormatProvider & ICustomFormatter interfaces, and they way they are handled by .NET.

IFormatProvider is a .NET Framework Interface that should be used, by implementing its single public object GetFormat(Type) method, when there is a need to implement custom formatting of data like String and DateTime.

The public object GetFormat(Type) method simply returns an object that in turns is available to supply all available information to continue the formatting process. The Type passed in by the Framework is meant to give the implementor a way to decide which type to return back. Its like a Factory Method Design Pattern where the "formatType" is the type expected to be returned.
class MyProvider : IFormatProvider { public object GetFormat(Type formatType) { object result = null; //* Factory Method if (formatType == typeof( ICustomFormatter)) //* Some object, will be disc…

Design API for Multiple Different Clients

Today I want to talk about common design challenges related to architecture of robust APIs, designed to be consumed by multiple clients with different needs.

Our use case is the following: We need to build a N-Tier Web REST/SOAP API that is supposed to read/write data from a DB, perform some processing on that data and expose those methods to our API consumers.

In addition we have multiple different API clients each with different needs, meaning we can't just expose a rigid set of functions with a defined group of DTOs (Data Transfer Objects).
DTO vs POCO Before start diving I want to explain shortly the difference between these two controversial concepts.
DTO Objects that are designed to transfer data between edges (i.e. between processes, functions, server & clients etc'). Typically DTOs will contain only simple properties with no behavior.
POCO Objects that are designed to reflect the internal business data model. For example if you have an eCommerce platform you will…