Design Patterns was made to solve problems with code and the way it looks and works. Abstract Factory Pattern was made to improve code responsible for creating dependencies between part of the functionality. This pattern helps with avoiding if statements with options for all currently used functionality in your code.
In this post you will find:
- example situation when to use Abstract Factory pattern
- Abstract Factory code structure in Java
- example how to use Abstract Factory
Exemplary Situation
We have a table, the table could be made of wood. We can have specific wood species e.g. oak or beech. Next, we have factories, one makes tables of Oakwood and the other one make it using beechwood. Now, let’s think about in Object Oriented way. These factories making the same thing, they have a product of the same type but build from different components. So we can have an interface with the common attributes that other class can inherit.
Let’s code it!
Abstract Factory Pattern
First the Table interface.
1 2 3 |
public interface Table { void treeSpecies(); } |
Here, we have one method treeSpecies(). Feel free to add more.
Next, we have the TableFactory interface.
1 2 3 |
public interface TableFactory { Table createTable(); } |
This interface has a method createTable() with type Table.
It’s time for first class OakenTable.
1 2 3 4 5 6 |
public class OakenTable implements Table { @Override public void treeSpecies() { System.out.println("This table is made of Oakwood."); } } |
We implement Table interface and implement methods with our own response form method.
TIP: In IntelliJ IDEA you can simply implement the method: first of all type implemented interface name and click ALT + ENTER on the keyboard and you will see a menu, then click ENTER on the Implement methods and select methods to implement, finally click ENTER or OK.
Now, it’s time for our factory.
1 2 3 4 5 6 |
public class OakWoodFactory implements TableFactory { @Override public Table createTable() { return new OakenTable(); } } |
Here, we implement TableFactory and in createTable() we return a new instance of the OakenTable class.
Let’s make the same steps for the BeechenTable.
1 2 3 4 5 6 |
public class BeechenTable implements Table { @Override public void treeSpecies() { System.out.println("This table is made of beechwood."); } } |
1 2 3 4 5 6 |
public class BeechWoodFactory implements TableFactory { @Override public Table createTable() { return new BeechenTable(); } } |
How to use Abstract Factory?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public class Client { public static void main(String[] args) { TableFactory factory; Table table; factory = new OakWoodFactory(); table = factory.createTable(); table.treeSpecies(); System.out.println("Next Factory:"); factory = new BeechWoodFactory(); table = factory.createTable(); table.treeSpecies(); } } |
Console output:
As can you see, we set the type of variables with our interfaces. Next, on the factory, we create new OakWoodFactory, then, on the table variable we call createTable() and on the end, we call treeSpecies() that print to the console the result of our code. The same thing is done with the Beechwood.
All code you can find on my Github: AbstractFactoryPattern
To learn this structure write it on your own example, this is the best way to learn. Feel free to ask questions. Hope you enjoy.
Good luck!
Nie masz swoje języka, antypolaku ! 🙁
Yes, I have 🙂