Problem

Application portability between platforms is often not considered in advance. The application will need to support different databases, windowing systems, and operating systems. Case statements with options for each platform to be supported begin to appear everywhere throughout the codebase.

Solution

Provide an interface for creating families of related and dependent objects without specifying their concrete classes. Create a hierarchy that can encapsulate the appropriate constructions for each supported platform.

Related Patterns

Discussion

The Abstract Factory defines a Factory Method per product. Clients never create platform objects directly. Instead, they ask the Abstract Factory to do that. Because the service provided is so pervasive, it is often implemented as a Singleton.

Examples

A real-world example of the Abstract Factory pattern would be part stamping machines in an actual factory. When different parts need to be stamped, a different form can be swapped into the presses.

A software example would be the ToolBuilder in SmallTalk. Using the ToolBuilder, we can easily plug different windowing systems, among others, into our application.

Code

This snippet is an example in C# of an Abstract Factory. The appropriate factory object (which knows how to create the UI elements for that platform) is created at run-time.

interface IButton{
  void Paint();
}
interface IGUIFactory{
  IButton CreateButton();
}

class WinFactory: IGUIFactory{
  public IButton CreateButton(){
    return new WinButton();
  }
}
class OSXFactory: IGUIFactory{
  public IButton CreateButton(){
    return new OSXButton();
  }
}
static void Main(){
  var appearance = Settings.Appearance;
  IGUIFactory factory;
  switch(appearance){
    case Appearance.Win:
      factory = new WinFactory();
      break;
    case Appearance.OSX:
      factory = new OSXFactory();
      break;
    default:
      throw new System.NotImplementedException();
  }
  var button = factory.CreateButton();
  button.paint();
}