Implement Abstract Factory Design Pattern in Java with an Example

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

  1. Button Interface: This defines the method render() that will be implemented by concrete button classes.
  2. Concrete Implementations:
  • WindowsButton: Implements the Button interface to render a Windows-style button.
  • MacButton: Implements the Button interface to render a Mac-style button.
  1. GUIFactory Interface: This defines a method createButton() that will be implemented by concrete factories.
  2. Concrete Factories:
  • WindowsFactory: Implements the GUIFactory interface to create a WindowsButton.
  • MacFactory: Implements the GUIFactory interface to create a MacButton.
  1. Application Class: This class uses a GUIFactory to create a button. It has a method renderButton() to render the button created by the factory.
  2. Main Class: In the main method, we determine the operating system and create the appropriate factory (WindowsFactory or MacFactory). We then create an instance of Application, passing the factory, and call renderButton() 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.

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *