The Abstract Factory Design Pattern is a creational design pattern that provides an interface for creating families of related or dependent objects without specifying their concrete classes. This pattern is particularly useful when the system needs to be independent of how its objects are created, composed, and represented.
Example: Abstract Factory Design Pattern
In this example, we will create a graphical user interface (GUI) where we have two types of buttons: Windows and Mac. We will use an abstract factory to create buttons for different operating systems.
Step 1: Define the Button Interface
// Button.java
public interface Button {
void render();
}
Step 2: Create Concrete Implementations for Buttons
// WindowsButton.java
public class WindowsButton implements Button {
@Override
public void render() {
System.out.println("Rendering a Windows Button.");
}
}
// MacButton.java
public class MacButton implements Button {
@Override
public void render() {
System.out.println("Rendering a Mac Button.");
}
}
Step 3: Define the GUI Factory Interface
// GUIFactory.java
public interface GUIFactory {
Button createButton();
}
Step 4: Create Concrete Factories
// WindowsFactory.java
public class WindowsFactory implements GUIFactory {
@Override
public Button createButton() {
return new WindowsButton();
}
}
// MacFactory.java
public class MacFactory implements GUIFactory {
@Override
public Button createButton() {
return new MacButton();
}
}
Step 5: Create a Client Class
// Application.java
public class Application {
private Button button;
public Application(GUIFactory factory) {
button = factory.createButton();
}
public void renderButton() {
button.render();
}
}
Step 6: Using the Abstract Factory in the Main Class
// Main.java
public class Main {
public static void main(String[] args) {
GUIFactory factory;
String os = System.getProperty("os.name").toLowerCase();
// Determine the operating system and create the appropriate factory
if (os.contains("win")) {
factory = new WindowsFactory();
} else if (os.contains("mac")) {
factory = new MacFactory();
} else {
throw new UnsupportedOperationException("Unsupported operating system");
}
Application app = new Application(factory);
app.renderButton();
}
}
Explanation of the Code
- Button Interface: This defines the method
render()
that will be implemented by concrete button classes. - Concrete Implementations:
- WindowsButton: Implements the
Button
interface to render a Windows-style button. - MacButton: Implements the
Button
interface to render a Mac-style button.
- GUIFactory Interface: This defines a method
createButton()
that will be implemented by concrete factories. - Concrete Factories:
- WindowsFactory: Implements the
GUIFactory
interface to create aWindowsButton
. - MacFactory: Implements the
GUIFactory
interface to create aMacButton
.
- Application Class: This class uses a
GUIFactory
to create a button. It has a methodrenderButton()
to render the button created by the factory. - Main Class: In the
main
method, we determine the operating system and create the appropriate factory (WindowsFactory
orMacFactory
). We then create an instance ofApplication
, passing the factory, and callrenderButton()
to display the button.
Output
When you run the Main
class on a Windows machine, the output will be:
Rendering a Windows Button.
And on a Mac machine, the output will be:
Rendering a Mac Button.
Conclusion
The Abstract Factory Design Pattern allows you to create families of related or dependent objects without specifying their concrete classes. This promotes loose coupling and increases flexibility in your code, making it easier to introduce new types of objects or support additional platforms in the future.