// Abstract product interfaces
interface Button {
    void paint();
}

interface Checkbox {
    void paint();
}
class WindowsButton implements Button {
    @Override
    public void paint() {
        System.out.println("Rendering a button in Windows style");
    }
}

class WindowsCheckbox implements Checkbox {
    @Override
    public void paint() {
        System.out.println("Rendering a checkbox in Windows style");
    }
}

class MacOSButton implements Button {
    @Override
    public void paint() {
        System.out.println("Rendering a button in MacOS style");
    }
}

class MacOSCheckbox implements Checkbox {
    @Override
    public void paint() {
        System.out.println("Rendering a checkbox in MacOS style");
    }
}
// Abstract factory interface
interface GUIFactory {
    Button createButton();
    Checkbox createCheckbox();
}

// Concrete factories
class WindowsFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new WindowsButton();
    }

    @Override
    public Checkbox createCheckbox() {
        return new WindowsCheckbox();
    }
}

class MacOSFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new MacOSButton();
    }

    @Override
    public Checkbox createCheckbox() {
        return new MacOSCheckbox();
    }
}
// Client code
class Application {
    private Button button;
    private Checkbox checkbox;

    public Application(GUIFactory factory) {
        button = factory.createButton();
        checkbox = factory.createCheckbox();
    }

    public void paint() {
        button.paint();
        checkbox.paint();
    }
}
public class Main {
    public static void main(String[] args) {
        // Create Windows GUI
        GUIFactory windowsFactory = new WindowsFactory();
        Application windowsApp = new Application(windowsFactory);
        windowsApp.paint();

        System.out.println();

        // Create MacOS GUI
        GUIFactory macFactory = new MacOSFactory();
        Application macApp = new Application(macFactory);
        macApp.paint();
    }
}
Rendering a button in Windows style
Rendering a checkbox in Windows style

Rendering a button in MacOS style
Rendering a checkbox in MacOS style

// Abstract products
interface Connection {
    void open();
    void close();
}

interface Command {
    void execute(String query);
}

interface ResultSet {
    void getResults();
}
// Abstract factory
interface DatabaseFactory {
    Connection createConnection();
    Command createCommand();
    ResultSet createResultSet();
}
// Concrete products for MySQL
class MySQLConnection implements Connection {
    public void open() {
        System.out.println("Opening MySQL connection");
    }
    public void close() {
        System.out.println("Closing MySQL connection");
    }
}

class MySQLCommand implements Command {
    public void execute(String query) {
        System.out.println("Executing MySQL query: " + query);
    }
}

class MySQLResultSet implements ResultSet {
    public void getResults() {
        System.out.println("Getting results from MySQL database");
    }
}
// Concrete products for PostgreSQL
class PostgreSQLConnection implements Connection {
    public void open() {
        System.out.println("Opening PostgreSQL connection");
    }
    public void close() {
        System.out.println("Closing PostgreSQL connection");
    }
}

class PostgreSQLCommand implements Command {
    public void execute(String query) {
        System.out.println("Executing PostgreSQL query: " + query);
    }
}

class PostgreSQLResultSet implements ResultSet {
    public void getResults() {
        System.out.println("Getting results from PostgreSQL database");
    }
}
// Concrete factories
class MySQLFactory implements DatabaseFactory {
    public Connection createConnection() {
        return new MySQLConnection();
    }
    public Command createCommand() {
        return new MySQLCommand();
    }
    public ResultSet createResultSet() {
        return new MySQLResultSet();
    }
}

class PostgreSQLFactory implements DatabaseFactory {
    public Connection createConnection() {
        return new PostgreSQLConnection();
    }
    public Command createCommand() {
        return new PostgreSQLCommand();
    }
    public ResultSet createResultSet() {
        return new PostgreSQLResultSet();
    }
}
// Client code
class DatabaseClient {
    private Connection connection;
    private Command command;
    private ResultSet resultSet;

    public DatabaseClient(DatabaseFactory factory) {
        connection = factory.createConnection();
        command = factory.createCommand();
        resultSet = factory.createResultSet();
    }

    public void performDatabaseOperations() {
        connection.open();
        command.execute("SELECT * FROM users");
        resultSet.getResults();
        connection.close();
    }
}