The Abstract Factory Pattern consists of four main components:
click()
and render()
.click()
and render()
methods.First, you need to define the abstract product interfaces. For example, let’s create an abstract button and an abstract checkbox:
// Abstract Product: Button
interface Button {
void click();
}
// Abstract Product: Checkbox
interface Checkbox {
void check();
}
Next, define the abstract factory interface that declares methods for creating the abstract products:
// Abstract Factory
interface GUIFactory {
Button createButton();
Checkbox createCheckbox();
}
Create the concrete product classes that implement the abstract product interfaces. For example, Windows - style and Mac - style products:
// Concrete Product: WindowsButton
class WindowsButton implements Button {
@Override
public void click() {
System.out.println("Windows button clicked.");
}
}
// Concrete Product: WindowsCheckbox
class WindowsCheckbox implements Checkbox {
@Override
public void check() {
System.out.println("Windows checkbox checked.");
}
}
// Concrete Product: MacButton
class MacButton implements Button {
@Override
public void click() {
System.out.println("Mac button clicked.");
}
}
// Concrete Product: MacCheckbox
class MacCheckbox implements Checkbox {
@Override
public void check() {
System.out.println("Mac checkbox checked.");
}
}
Create the concrete factory classes that implement the abstract factory interface:
// Concrete Factory: WindowsFactory
class WindowsFactory implements GUIFactory {
@Override
public Button createButton() {
return new WindowsButton();
}
@Override
public Checkbox createCheckbox() {
return new WindowsCheckbox();
}
}
// Concrete Factory: MacFactory
class MacFactory implements GUIFactory {
@Override
public Button createButton() {
return new MacButton();
}
@Override
public Checkbox createCheckbox() {
return new MacCheckbox();
}
}
Finally, use the abstract factory in the client code:
// Client code
public class Client {
public static void main(String[] args) {
// Create a Windows factory
GUIFactory factory = new WindowsFactory();
Button button = factory.createButton();
Checkbox checkbox = factory.createCheckbox();
button.click();
checkbox.check();
// Switch to Mac factory
factory = new MacFactory();
button = factory.createButton();
checkbox = factory.createCheckbox();
button.click();
checkbox.check();
}
}
The complete code example is provided above in the Usage Methods section. Here is a summary of the main classes and their interactions:
// Abstract Product: Button
interface Button {
void click();
}
// Abstract Product: Checkbox
interface Checkbox {
void check();
}
// Abstract Factory
interface GUIFactory {
Button createButton();
Checkbox createCheckbox();
}
// Concrete Product: WindowsButton
class WindowsButton implements Button {
@Override
public void click() {
System.out.println("Windows button clicked.");
}
}
// Concrete Product: WindowsCheckbox
class WindowsCheckbox implements Checkbox {
@Override
public void check() {
System.out.println("Windows checkbox checked.");
}
}
// Concrete Product: MacButton
class MacButton implements Button {
@Override
public void click() {
System.out.println("Mac button clicked.");
}
}
// Concrete Product: MacCheckbox
class MacCheckbox implements Checkbox {
@Override
public void check() {
System.out.println("Mac checkbox checked.");
}
}
// Concrete Factory: WindowsFactory
class WindowsFactory implements GUIFactory {
@Override
public Button createButton() {
return new WindowsButton();
}
@Override
public Checkbox createCheckbox() {
return new WindowsCheckbox();
}
}
// Concrete Factory: MacFactory
class MacFactory implements GUIFactory {
@Override
public Button createButton() {
return new MacButton();
}
@Override
public Checkbox createCheckbox() {
return new MacCheckbox();
}
}
// Client code
public class Client {
public static void main(String[] args) {
// Create a Windows factory
GUIFactory factory = new WindowsFactory();
Button button = factory.createButton();
Checkbox checkbox = factory.createCheckbox();
button.click();
checkbox.check();
// Switch to Mac factory
factory = new MacFactory();
button = factory.createButton();
checkbox = factory.createCheckbox();
button.click();
checkbox.check();
}
}
The Abstract Factory Pattern is a powerful and flexible design pattern in Java that allows you to create families of related objects without specifying their concrete classes. It provides a high level of decoupling between the client code and the products, making the code more maintainable and extensible. By following the usage methods, common practices, and best practices described in this blog, you can effectively use the Abstract Factory Pattern in your Java applications.