Abstract Factory Pattern
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.
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.
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: