DEV Community

eidher
eidher

Posted on • Updated on

Abstract Factory Pattern

Provides an interface for creating families of related or dependent objects without specifying their concrete classes.

Alt Text

Participants

  • AbstractFactory: declares an interface for operations that create abstract products.
  • ConcreteFactory: implements the operations to create concrete product objects.
  • AbstractProduct: declares an interface for a type of product object.
  • Product: defines a product object to be created by the corresponding concrete factory. Implements the AbstractProduct interface.
  • Client: uses interfaces declared by AbstractFactory and AbstractProduct classes.

Code

public class Main {

    public static void main(String[] args) {
        // Abstract factory #1
        AbstractFactory factory1 = new ConcreteFactory1();
        Client client1 = new Client(factory1);
        client1.run();

        // Abstract factory #2
        AbstractFactory factory2 = new ConcreteFactory2();
        Client client2 = new Client(factory2);
        client2.run();
    }
}

public interface AbstractFactory {

    AbstractProductA createProductA();

    AbstractProductB createProductB();

}

public class ConcreteFactory1 implements AbstractFactory {

    @Override
    public AbstractProductA createProductA() {
        return new ProductA1();
    }

    @Override
    public AbstractProductB createProductB() {
        return new ProductB1();
    }

}

public class ConcreteFactory2 implements AbstractFactory {

    @Override
    public AbstractProductA createProductA() {
        return new ProductA2();
    }

    @Override
    public AbstractProductB createProductB() {
        return new ProductB2();
    }

}

public interface AbstractProductA {

}

public interface AbstractProductB {
    void interact(AbstractProductA a);
}

public class ProductA1 implements AbstractProductA {

}

public class ProductB1 implements AbstractProductB {

    @Override
    public void interact(AbstractProductA a) {
        System.out.println(this.getClass().getSimpleName() + " interacts with " + a.getClass().getSimpleName());
    }

}

public class ProductA2 implements AbstractProductA {

}

public class ProductB2 implements AbstractProductB {

    @Override
    public void interact(AbstractProductA a) {
        System.out.println(this.getClass().getSimpleName() + " interacts with " + a.getClass().getSimpleName());
    }

}

public class Client {

    private AbstractProductA abstractProductA;
    private AbstractProductB abstractProductB;

    public Client(AbstractFactory factory) {
        abstractProductB = factory.createProductB();
        abstractProductA = factory.createProductA();
    }

    public void run() {
        abstractProductB.interact(abstractProductA);
    }
}
Enter fullscreen mode Exit fullscreen mode

Output

ProductB1 interacts with ProductA1
ProductB2 interacts with ProductA2
Enter fullscreen mode Exit fullscreen mode

Discussion (0)