It’s a creational design pattern in which related products are grouped together whose behavior depends on their family, and the family factories creates objects of those related products.

Purpose: Similar purpose as Factory Pattern i.e., program to interface, not to implementation.

The popular example is Widgets{Button, TextField} which are related products grouped together, and they behave differently based on the OS{Windows, Mac}. The client code is programmed to interfaces i.e., {Button, TextField, GuiFactory}. Below is the UML Class Diagram for the same.

Factory method pattern

Here is another example, let’s say a film production house has urgent requirement to onboard a film director, actor for a script ready project. Here is an example implementation of Abstract Factory pattern of the same.

Product1 - Actor

interface Actor {
  String contact();
}

class HollywoodFilmActor implements Actor {
  @Override
  public String contact() {
    return getContactNumber();
  }

  private String getContactNumber() {
    // TODO: Logic to fetch contact number
    return "";
  }
}

class IndianFilmActor implements Actor {
  public String contact() {
    return getContactNumber();
  }

  private String getContactNumber() {
    // TODO: Logic to fetch contact number
    return "";
  }
}

Product2 - Director

interface Director {
  String contact();
}

class HollywoodFilmDirector implements Director {
  @Override
  public String contact() {
    return getContactNumber();
  }

  private String getContactNumber() {
    // TODO: Logic to fetch contact number
    return "";
  }
}

class IndianFilmDirector implements Director {
  @Override
  public String contact() {
    return getContactNumber();
  }

  private String getContactNumber() {
    // TODO: Logic to fetch contact number
    return "";
  }
}

Factories

interface FilmIndustry {
  Actor getAvailableActor();
  Director getAvailableDirector();
}

class HollywoodFilmIndustry implements FilmIndustry {
  @Override
  public Actor getAvailableActor() {
    return new HollywoodFilmActor();
  }

  @Override
  public Director getAvailableDirector() {
    return new HollywoodFilmDirector();
  }
}

class IndianFilmIndustry implements FilmIndustry {
  @Override
  public Actor getAvailableActor() {
    return new IndianFilmActor();
  }

  @Override
  public Director getAvailableDirector() {
    return new IndianFilmDirector();
  }
}

Sample Client code snippet

public class Demo {

  private enum FilmIndustryType {
    HOLLYWOOD,
    INDIAN
  }

  /*-
   * This method is Programmed to interface
   *
   * Addition of new subtypes of FilmIndustry
   * doesn't require a change in this method.
   */
  static void contactFilmProfessional(FilmIndustry filmIndustry) {
    filmIndustry.getAvailableActor().contact();
    filmIndustry.getAvailableDirector().contact();
  }

  public static void main(String[] args) {
    // Assume production house is looking for actor and director from Indian Film Industry
    FilmIndustryType industryType = FilmIndustryType.INDIAN;
    switch (industryType) {
      case HOLLYWOOD:
        contactFilmProfessional(new HollywoodFilmIndustry());
        break;
      case INDIAN:
        contactFilmProfessional(new IndianFilmIndustry());
        break;
      default:
        throw new IllegalArgumentException("Invalid industry type");
    }
  }
}

Here is UML Class Diagram representation of the above code.

Factory method pattern

As shown in the above diagram, there are more than one product class hierarchies, and a single factory hierarchy. Each sub-factory is responsible for creation of specific sub-products.

References:

  1. Abstract Factory Pattern