Abstract factory is a creational pattern. This pattern provides an interface for creating families of related or dependent objects without describing their concrete classes.
In my last writeup about Factory Pattern I described a situation of an imaginary programmer who just created a motorbike sharing platform. Within few days his platform got so popular that customers started demanding for cars too. Instead of re-writing his whole codebase we saw how he implemented Factory pattern to accumulate both car and bike rides in his platform.
Today he is planning to add a new feature in his platform. He want to give the customers the ability to choose the category of his ride like deluxe and premium. He also wants to write well manageable code to support this new features. His previous implementation was following factory pattern, where the products of his transport factory was either car ride or bike ride. Now he has to produce deluxe/premium car and deluxe/premium bike rides. And he smells that he need one more layer of abstraction over his factory, thus he decides to follow Abstract Factory pattern for his use case.
As the definition states that, abstract factory provides interface for creating families of related of dependent objects. Here car ride either deluxe or premium, are more or less related right? So the implementation would look like this from the birds eye view:
Let’s see some code now. First he creates interfaces for two category of rides, premium and deluxe:
Then he creates concrete ride classes that implements this interfaces:
These classes will be the final product for his factory. But now he has to create two factories, car and bike which will encapsulate the final products this way:
Now his final layer of abstraction is like this:
If you can see the previous post, you may see that the final layer of abstraction is very minimal between previous and new implementation. Using abstract factory pattern he was able to hide out almost all of his complex logic from user and keep the implementation clean.
You may ask why wouldn’t he write his implementation with abstract factory in the first place? Well, because he didn’t needed to, right? There is no triumph in writing complex codes if it doesn’t alleviate any pain point. As his business getting bigger, new services are coming up it was necessary to restructure his code. He didn’t knew from the start that he would be this big in no time.
In real world too, design often starts with simplest pattern factory and then evolves to abstract factory, prototype of builder. These patterns give more flexibility and also take away simplicity. We will see about them soon.