Abstract Factory Method Pattern

The Abstract Factory pattern is a creational design pattern that provides an interface for creating families of related or dependent objects without specifying their concrete classes.

The pattern is essentially a super factory which creates other factories (Factory of factories). The Abstract Factory pattern is also known as the "Kit" because it's great when you want to provide a high-level interface for creating many related objects, i.e., an entire family of products.

Let's consider a user interface example with a family of themes. We could have a Dark theme and a Light theme, each of which needs a different type of Button, Menu, and Panel. We could use the Abstract Factory pattern to create a separate factory for each theme that knows how to create the appropriate Button, Menu, and Panel for that theme.

In Java, an example could look like this:

// Abstract product A public interface Button { void render(); } // Abstract product B public interface Menu { void render(); } // Concrete product A1 public class DarkThemeButton implements Button { public void render() { System.out.println("Rendering Dark Theme Button..."); } } // Concrete product B1 public class DarkThemeMenu implements Menu { public void render() { System.out.println("Rendering Dark Theme Menu..."); } } // Concrete product A2 public class LightThemeButton implements Button { public void render() { System.out.println("Rendering Light Theme Button..."); } } // Concrete product B2 public class LightThemeMenu implements Menu { public void render() { System.out.println("Rendering Light Theme Menu..."); } } // Abstract Factory public interface GUIFactory { Button createButton(); Menu createMenu(); } // Concrete Factory 1 public class DarkThemeGUIFactory implements GUIFactory { public Button createButton() { return new DarkThemeButton(); } public Menu createMenu() { return new DarkThemeMenu(); } } // Concrete Factory 2 public class LightThemeGUIFactory implements GUIFactory { public Button createButton() { return new LightThemeButton(); } public Menu createMenu() { return new LightThemeMenu(); } } // Client code public class Client { private Button button; private Menu menu; public Client(GUIFactory factory) { button = factory.createButton(); menu = factory.createMenu(); } public void renderGUI() { button.render(); menu.render(); } public static void main(String[] args) { Client darkThemeClient = new Client(new DarkThemeGUIFactory()); darkThemeClient.renderGUI(); Client lightThemeClient = new Client(new LightThemeGUIFactory()); lightThemeClient.renderGUI(); } }

In this example, Button and Menu are the abstract products. DarkThemeButton, DarkThemeMenu, LightThemeButton, and LightThemeMenu are the concrete products. GUIFactory is the Abstract Factory that declares a set of methods for creating each abstract product. DarkThemeGUIFactory and LightThemeGUIFactory are the Concrete Factories that implement these creation methods to produce the concrete products. The Client uses only interfaces declared by Abstract Factory and Abstract Product classes.