Design Pattern: Factory Method Vs Abstract Factory


What is the difference between Factory Method and Abstract Factory, and when to use which?

First, remember they both belong to Creational Patten, which aims to provide proper way in dealing with object creation.

Then, let's talk about the difference and relationship between them.


Factory Method is a special case of Template Method Pattern, in which base class defines the algorithm skeleton and defers some of the steps involved in the generic algorithm to subclass.  An example of this is how to create a customized view in Android - your create subclass of View and override the onDraw(), which is a Template Method.

public class View() {
     void draw(){
          drawBackground();
          onDraw(canvas);
          drawOthers();
     }
     abstract void onDraw();
 }
public class MyView extends View {
     void onDraw(Canvas canvas) {
          canvas.drawRect(...)
     }
}

In comparison, Factory Method, defers the creation of its aggregated object to subclass - or we can say defer its own instantiation to subclass. In following example, MazeGame depends on its subclass to create Room object and instantiate itself. Factory Method is also called Virtual Constructor, in the sense that base class relies subclass to construct properly.

public class MazeGame {
     public MazeGame() {
        Room room1 = makeRoom();
        Room room2 = makeRoom();
        room1.connect(room2);
        this.addRoom(room1);
        this.addRoom(room2);
}
    abstract protected Room makeRoom();
}

public class MagicMazeGame extends MazeGame {
   @Override
protected Room makeRoom() {return new MagicRoom()};
}

Abstract Factory.  Its definition is "Provide an interface for creating families of related or dependent objects without specifying their concrete classes". Compared with Factory Method, the main difference is Abstract Factory is used to create multiply types of object.

Let's see an example. Car, which is a client, uses the PartFactory to create various parts needed by a Car. There can be different implementation of PartFactory and Client does not care.

   public class Car{
    public Car(PartFactory  partFactory) {       
        mWheel = partFactory->makeWheel();
        Window = partFactory->makeWindow();
        Engine = partFactory->makeEngine();
    }
 }
  public interface PartFactory {
    Room makeWheel();
    Door makeWindow();
    Engine makeEngine();
  }
 public FortPartFacotry implements PartFactory {
   Wheel makeWheel()   {return FordWheel()}
   Window makeWindow() {return FordWindow()};
   Engine makeEngine() {return FordEngine()};
  }
  // to create a Car
  new Car(new FortPartFacotry() )

However, it is OK to still use Factory Method, even we have multiply object to create.  

 public class Car{
    public Car() {
        mWheel = makeWheel();
        Window = makeWindow();
        Engine = makeEngine();
    }
    abstract protected Wheel  makeWheel();
    abstract protected Window makeWindow();
    abstract protected Engine makeEngine();
 }

 public class FordCar extends Car{
   protected Wheel makeWheel()   {return FordWheel()}
   protected Window makeWindow() {return FordWindow()};
   protected Engine makeEngine() {return FordEngine()};
 }

Which is better? Not obvious in this specific case. In the Abstract Factory Patten, all the creation methods are extract in a separate interface. And the composition is used instead of inheritance, which is believed to be a good thing. 

Similar, when there is only one object to create, you are not prohibited from using Abstract Factory  Back to Maze example, 

public class MazeGame {
    public MazeGame(RoomFactory roomFactory) {
        Room room1 = roomFactory.makeRoom();
        Room room2 = roomFactory.makeRoom();
        room1.connect(room2);
        this.addRoom(room1);
        this.addRoom(room2);
    }
 }
public interface RoomFactory {
    Room makeRoom();
}
public class MagicRoomFactory implements RoomFactory {
    @Override
    Room makeRoom() { return new MagicRoom();}
}
new MazeGame(new MagicRoomFactory())

So the real distinction between “Abstract Factory” and “Factory Method” is not the number of the object need to be created but the former uses both composition (b/w client and Factory) and inheritance (b/w abstract Factory and concrete Factory) while the later uses only inheritance.

What is the conclusion then? Well, no actual one. However, once you comprehend what we talked here, you should be able to make informed decision between those two.