Abstract Factory Design Pattern

Type: Creational Design Pattern

Definition: Creates an instance of several families of classes. Helps to control objects creation.

UML Classical Diagram:

Example UML Diagram

To be more specific we will create factory that produces sweets. Here the UML example for the code that will be shown in the next steps.

  • impl = implements

The Code

1. Create Abstract Products
First of all let’s develop type of sweets that we will be delivering later from factories to our client (that will happen in the ClientDemo class with the main() method). We can create and deliver cakes and bisuits.
 
interface Cake {
    String getCream();

    String getDough();
}
 
public interface Biscuit {
}
1. Create Concrete Products
Cakes and bisuits could be different types according to people preferences. We will prepare chocolate and honey cakes.
 
public class ChocolateCake implements Cake {

    @Override
    public String getDough() {
        return "chocolate dough";
    }

    @Override
    public String getCream() {
        return "chocolate cream";
    }

    @Override
    public String toString() {
        return "Enjoy Chocolate Cake made of Dough= " + this.getDough() + ", Cream=" + this.getCream();
    }
}
 
public class HoneyCake implements Cake {

    @Override
    public String getDough() {
        return "honey dough";
    }

    @Override
    public String getCream() {
        return "honey cream";
    }

    @Override
    public String toString() {
        return "Enjoy Honey Cake made of Dough= " + this.getDough() + ", Cream=" + this.getCream();
    }
}
And we will prepare chocolate and honey biscuits.
 
public class ChocolateBiscuit implements Biscuit {

    @Override
    public String toString() {
        return "Enjoy your Chocolate Biscuits!";
    }
}
 
public class HoneyBiscuit implements Biscuit {
    @Override
    public String toString() {
        return "Enjoy your Honey Biscuits!";
    }
}
3. Create Abstract Factory
This is an example of an AbstractFactory which is represented as an interface to create different types of abstract Products (Cake and Bisuit in our case)
 
public interface AbstractSweetsFactory {
    Cake getCake();

    Biscuit getBiscuit();
}
}
4. Create Concrete Factories
Next step is to create Concrete Factories that implement the AbstractFactory interface. Concrete Factories should return conrete types of Products. As concrete products we have:
  • honey cakes (HoneyCake),
  • chocolate cakes (ChocolateCake),
  • honey bisuits (HoneyBiscuit),
  • and chocolate bisuits (Chocolate Bisuit).
So, we can create one factory that will deliver products made of honey and another factory that will create products with chocolate. (HoneyFactory and ChocolateFactory)
 
public class HoneyFactory implements AbstractSweetsFactory {
    @Override
    public Cake getCake() {
        return new HoneyCake();
    }

    @Override
    public Biscuit getBiscuit() {
        return new HoneyBiscuit();
    }
}
}
 
public class ChocolateFactory implements AbstractSweetsFactory {
    @Override
    public Cake getCake() {
        return new ChocolateCake();
    }

    @Override
    public Biscuit getBiscuit() {
        return new ChocolateBiscuit();
    }
}

DemoClient Result

 
public class DemoClient {
    public static void main(String[] args) {
        System.out.println("Let's get a honey cake and biscuits");
        AbstractSweetsFactory honeyCakeFactory = new HoneyFactory();
        System.out.println(honeyCakeFactory.getCake());
        System.out.println(honeyCakeFactory.getBiscuit());

        System.out.println("\nLet's get a napoleon cake and biscuits");
        AbstractSweetsFactory napoleonCakeFactory = new NapoleonFactory();
        System.out.println(napoleonCakeFactory.getCake());
        System.out.println(napoleonCakeFactory.getBiscuit());
    }
}
Output:
 
Let's get a honey cake and biscuits
Enjoy Honey Cake made of Dough= honey dough, Cream=honey cream
Enjoy your Honey Biscuits!

Let's get a napoleon cake and biscuits
Enjoy Napoleon Cake made of Dough= classical dough, Cream=butter cream
Enjoy your Napoleon Biscuits!

Advantages

  1. Details of set of objects implementetion are splitted from their usage by the Client.
  2. Client will not create objects by him/herself but AbstractFactory will. That can simplify the code from the objects creation as the Client is isolated from concrete objects creation.
  3. Concrete Factories make sure that the products which are used together whithin a concrete factory are the right ones. The client doesn’t know about the implementation and product families.

Disadvantages

    If the logic for some of the factories needs to be changed then an interface will have to be updated. When an interface has been changed then every particular Factory has to be modified as well. Until everything is needed is modified the Client is broken.

Practical Usage

  1. Providing data access to different data sources: PostresSQL Database, Oracle Database, etc. Different classes for getting access will be created. All of them will inherit from a base class that defines the common methods for loading, updating, removing, saving. When a client needs access to some database he/she will call AbstractFactory that knows which kind of data source it will load. Client doesn’t know the detail of actual loading.
     BaseAccess access = new PostreSQLAcess();
     access.load();
     
     BaseAccess access = new OracleSQLAcess();
     access.load(); 
  2. Abstract Factories are great for supporting multiple platforms while keeping your code-base unified.
  3. Good for creating different types of documents(letter, resume, feedback) in different formats (classical, stylized).

Interesting about the pattern

  1. AbstractFactory is an alternative to Facade. It is used to hide platform-specific classes.
  2. AbstractFactory are often implemented with FactoryMethods but it can be also implemented with Prototype design pattern.

Used resources:

Diagram creation: https://yuml.me/diagram/scruffy/class/draw

Examples from StackOverflow: https://stackoverflow.com/questions/2280170/why-do-we-need-abstract-factory-design-pattern

Continue Reading