DEV Community

Iyanu Falaye
Iyanu Falaye

Posted on

Design Patterns: Abstract Factory.

A creational pattern that provides an interface to create a family of related objects without specifying their concrete implementation. It comprises of many factory methods one for each object that needs to be created. Mainly used when a system needs to be independent of how its objects are created.

Motivation
When a system has multiple families of objects it needs to determine which object will be used at runtime.
Provides abstraction between concrete classes and their client to enforce flexibility.

Implementation
Imagine a family of furniture; chairs, tables, wardrobes. There are different variants of furniture; wooden & plastic in this case.
As we established previously, the abstract factory is also known as a factory of factories because it contains many factory methods. Therefore in case we are going to have factory methods that create a chair, table, and wardrobe.

public interface Chair {

    String createChair();
}

Enter fullscreen mode Exit fullscreen mode

As shown in the Chair interface the createChair method is the factory method and similarly, we have the same for tables and wardrobes as createTable and createWardrobe respectively.

public interface Table {

    String createTable();
}

Enter fullscreen mode Exit fullscreen mode
public interface Wardrobe {

    String createWardrobe();
}

Enter fullscreen mode Exit fullscreen mode

We know the users often request for the family of furniture so we have to create a FurnitureFactory that creates a chair, table, and wardrobe all at once.

public interface FurnitureFactory {

    Chair createChair();

    Table createTable();

    Wardrobe createWardrobe();

}
Enter fullscreen mode Exit fullscreen mode

Now, considering a user is looking to get a wooden furniture we are going to create concrete classes WoodenChair, WoodenTable, and WoodenTable that implements the the Chair, Table and Wardrobe interfaces.

public class WoodenChair implements Chair{
    @Override
    public String createChair() {
        return "Wooden Chair";
    }
}
Enter fullscreen mode Exit fullscreen mode
public class WoodenTable implements Table {

    @Override
    public String createTable() {
        return "Wooden Table";
    }
}

Enter fullscreen mode Exit fullscreen mode
public class WoodenWardrobe implements Wardrobe {
    @Override
    public String createWardrobe() {
        return "Wooden Wardrobe";
    }
}
Enter fullscreen mode Exit fullscreen mode

The WoodenFurnitureFactory class creates a the wooden furniture that the user needs by creating the objects in the concrete factory methods.

public class WoodenFurnitureFactory implements FurnitureFactory {
    @Override
    public Chair createChair() {
        return new WoodenChair();
    }

    @Override
    public Table createTable() {
        return new WoodenTable();
    }

    @Override
    public Wardrobe createWardrobe() {
        return new WoodenWardrobe();
    }
}

Enter fullscreen mode Exit fullscreen mode

Imagine another customer requests for a plastic furtniture, it is easy to creates plastic furnitures becuase we are depending on interfaces and we have a furniture factory (Abstract factory).

public class PlasticChair implements Chair {
    @Override
    public String createChair() {
        return "Plastic Chair";
    }
}
Enter fullscreen mode Exit fullscreen mode
public class PlasticTable implements Table{
    @Override
    public String createTable() {
        return "Plastic Table";
    }
}

Enter fullscreen mode Exit fullscreen mode
public class PlasticWardrobe implements Wardrobe{
    @Override
    public String createWardrobe() {
        return "Plastic Wardrobe";
    }
}

Enter fullscreen mode Exit fullscreen mode
public class PlasticFurnitureFactory implements FurnitureFactory{

    @Override
    public Chair createChair() {
        return new PlasticChair();
    }

    @Override
    public Table createTable() {
        return new PlasticTable();
    }

    @Override
    public Wardrobe createWardrobe() {
        return new PlasticWardrobe();
    }
}

Enter fullscreen mode Exit fullscreen mode

A user can request more variants e.g a metallic furniture and the it would be created in record time using the abstract factory pattern.
Now we run our code;

    FurnitureFactory woodenFactory = new WoodenFurnitureFactory();
        Chair woodenChair = woodenFactory.createChair();
        Table woodenTable = woodenFactory.createTable();
        Wardrobe woodenWardrobe = woodenFactory.createWardrobe();

        System.out.println("Wooden Factory makes " + woodenChair.createChair() + ", " +  woodenTable.createTable() + ", " + woodenWardrobe.createWardrobe());

        FurnitureFactory plasticFactory = new PlasticFurnitureFactory();

        Chair plasticChair = plasticFactory.createChair();
        Table plasticTable = plasticFactory.createTable();
        Wardrobe plasticWardrobe = plasticFactory.createWardrobe();

        System.out.println("Plastic Factory makes " + plasticChair.createChair() + ", " +  plasticTable.createTable() + ", " + plasticWardrobe.createWardrobe());

Enter fullscreen mode Exit fullscreen mode

Here's the output.

Wooden Factory makes Wooden Chair, Wooden Table, Wooden Wardrobe
Plastic Factory makes Plastic Chair, Plastic Table, Plastic Wardrobe
Enter fullscreen mode Exit fullscreen mode

Advantages

  1. It promotes an approach to code for interface instead of concrete implementation. 2.We can add more variants of the same family of object easily.

Disadvantages

  1. Introduces complexity with multiple interfaces.

Real Life Examples
Cross-platform UI Toolkit

Conclusion
It provides high level approach to object creation particularlly systems that require family of related objects, enhancing cosistency and decoupling. It promotes open close principle especially in the way the system is based on interfaces. To check the implementation via this link

Top comments (0)