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).
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
- Details of set of objects implementetion are splitted from their usage by the Client.
- 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.
- 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
- 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();
- Abstract Factories are great for supporting multiple platforms while keeping your code-base unified.
- Good for creating different types of documents(letter, resume, feedback) in different formats (classical, stylized).
Interesting about the pattern
- AbstractFactory is an alternative to Facade. It is used to hide platform-specific classes.
- 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