Time for another pattern. Abstract Factory (AF). Let's start with the GoF intent.
"Provide an interface for creating families of related or dependent objects without specifying their concrete classes"
There are many ways of arriving at this pattern when it comes to explaining it. One way which works for me is to think about a factory as something which produces objects. Abstract Factory could be something that the clients interact with and where factory itself has an abstracted nature. The most common usage of the abstract factory is when we need a set of objects which makes sense together. In the software world sometimes it is easy for the objects to get mixed up even if we design the classes correctly. That is where AF can play a critical role. Let's see an example.
In a recent project we did in my company we did have the following use case.
"To build a sales order system for non US distributors for a shoe manufacturer. Let's assume that we have to calculate freight for European distributors using UPS charges. Money will also be handled by the country distributor is in. We need to use the European shoe styling codes when it comes to the shipment going to Europe. For Asian countries the shoe style codes could be different from European countries. When it comes to taxes will use EURO tax laws in Europe and other countries will have to pay taxes as per their tax laws. Packing of shoes happens in different box forms can be done using different combinations which are defined based on the distributors location and shipping carrier availability"
After a bit of brainstorming we could quickly arrive at a solution might have looked something like what is shown below
Once you have come up with a design which in this case shows Strategy pattern in place the challenge is to make sure that the objects don't get all mixed up. For instance if you see the blue boxes which are marked by red borders you will notice that for a client (SalesOrder) it is possible to pick up EuropeanShoeStyle and AsianTaxApplicable objects and do the necessary calculations. This of course can be stopped from happening by building multiple checks at the code level which can check for the correct object set before an operation can be run on that set. But this would lead to programming horrors and code which we don't want to write and maintain.
Now how can we avoid this ? One way is to create the sets of objects which are not mixed up at the first place. This is a very good use case for AF pattern. If the client interacts with a AF which will have the responsibility of creating the correct set then we will be okay. Consider the next figure which shows the same
If you look at the green colour box above it is nothing but the AF we have been talking about. Now all it
does is that creates some more factories like EF (Europe Factory) or AF (Asian Factory) and the responsibility
of creating the correct set of objects is absorbed by these factories. For example EF will only create objects of EuropeanShoeStyling and EuropeTaxApplicable. What will eventually happen is that the correct sets of objects will now get created and (for instance EuropeanShoeStyling & EuropeTaxApplicable for SalesOrder for Europe) this will make code cleaner and easier to maintain.
Tomorrow if there is a requirement which demands to add a few more things it can be done in a clean way. For example AustralianShoeStyling and AustralianTaxes. We will of course need a factory like AUF under AbstractFactory to make sure that these objects are created in sets as others.
Comments are closed for this blog post