In the previous blog you would have seen Factory Pattern, this blog we will go along with Common Developer (CD) to have a look at what is Abstract Factory. After getting his dream car CD was happily driving it and showing it off to his friends and colleagues. Seeing CD’ car one of his colleague Another Common Developer (ACD) wanted to get a car for himself. But his requirement was different. He wanted to try different models and then select the best. ACD was not particular about a brand unlike CD who was very much particular about the brand Hyundai and also the model i10. ACD wanted to test drive different brand cars and then finalise on one or two and choose from among the short listed ones. ACD approached CD to get some tips on buying a car. After listening to ACD’ requirement CD suggested that he can approach a multi car brand showroom rather than a particular brands showroom. Taking CD’ advice ACD went to multi brand showroom and test drove many cars and finally settled for Toyota Camry. ACD called CD and informed him about his choice.
After finishing the call CD’ developer mind kicked in and started thinking how to implement ACD’ requirement in software terms. He has already implemented Factory pattern for solving his requirement where he was clear on which car he wanted and which brand he is looking for. After giving some thought CD noted down the following points.
There will be a set of different classes than the one in factory where everything was Hyundai brand of cars.
Different factories needed to create these different classes.
After doing a research CD found out that the best way to approach this scenario is to make use of the Abstract Factory pattern. There are many variations to the Abstract Factory and CD decided to try the two variations (Actually there is only one Abstract Factory proposed by the GOF. But over a period variations popped up. The second Abstract Factory pattern described in this blog is the one proposed by GOF.) Lets see the first variation. For the first implementation CD decided to build the building blocks of Abstract Factory. For this CD needed to create the products which the different factories can create. He thought of changing his Factory pattern implementation to incorporate Abstract Factory. The initial class created for factory pattern is listed below on which CD is planning to add new car models.
To incorporate Abstract Factory CD added new cars of different manufacturer. He added Ikon, Fiesta and Fusion models from Ford, Camry and Corrola models from Toyota and City, Civic and Accord models from Honda. The new class structure is show below.
From the above class diagram one can see that the new models are inheriting from the same Abstract Car class. The Initial product development is over. Now comes the factory creation. This implementation you can say is an extension of the first factory implementation method we saw in Factory pattern. In the first implementation of factory pattern we had only a concrete factory to create all the Hyundai cars. In the Abstract Factory implementation we will have base class from which all the car factories will inherit. The base class can be an abstract class or an interface. CD is making use of an interface called ICarFactory. The code is pasted below.
The interface, ICarFactory, has got a method called “CreateCar” which takes the car name as the string argument and returns a “Car” object. All the car factories will inherit from this interface and implement their car manufacturing methods. The other method in the interface is “CarModelAvailable”. This method will return a string which will list out the models available with the brand. The sample code of “HyundaiCarFactory” and “ToyotaCarFactory” is given below.
As you can see both the factory codes are nothing great, they just check the string and return the appropriate car model. The class diagram for the factories is given below.
As you can see from the diagram all the car factories inherit from the same interface. Each one has its own implementation of the “CreateCar” method which does the work of creating the respective car models of the company. As the factories are ready CD needed a place to assemble the cars and deliver them to the customer. For assembling the car CD created a class called the “AssemblyFloor”. The code for the class is shown below.
public Car DeliverCar(string theCarName)
The “AssemblyFloor” takes an “ICarFactory” implemented object as an argument in its constructor and sets it to one of its member variable. The “DeliverCar” method takes the car name as a string and calls the appropriate method of the factory to create the car. With the assembly floor the requirement to implement Abstract Factory is completed. While doing a code walkthrough CD found out that he has nearly four factories for the different brands. To create the factories dynamically, CD came up with an idea to have a factory to create the dynamic factory. So he created a factory for factory. The code is shown below.
Please note a very important point, the above class is not a part of the Abstract Factory, it is just a helper factory class. The helper class will help to create the factories based on different user’ requirement. The factory and products to be created by the factory are in place. CD wrote a Showroom class to make use of all the classes and see the behavior of Abstract Factory. The code of Showroom class is pasted below.
With the above code the abstract factory implementation is pretty much done.
Next CD thought of implementing the second approach to Abstract factory (the original pattern proposed by GOF). The difference which CD noted between Abstract Factory first approach and the new approach which he is going to implement is that in the second approach the products don’t have a single base class like that of the first approach. Instead the second approach has a set of products which inherit from their own base class. In the first approach all the products had a common base class whereas in the second approach each set of class had their own base class. Also the factory in the second approach will have the methods to create more than one product. Confused? Lets take the same car e.g. and work it out to have a better understanding. As CD found out that different products will have different base classes and they inherit from them, he decided to rework his class structure. CD kept the same base class structure for the car hierarchy, in addition to that he introduced new classes called “Engine”, “Chassis”, “Axle”, and “Wheel” which an integral part of a car. To incorporate the new classes in car CD changed the base “Car” class as shown below.
public IEngine Engine
public ICarChassis Chassis
public IAxle Axle
public IWheel Wheel
public abstract float CC
public abstract float Width
public abstract float Height
public abstract float GroundClearance
public abstract float MaxPower
public abstract float MaxTorque
public abstract float MaxSpeed
public abstract float TankCapacity
public abstract bool StartCar();
public string CarName
You can see CD has added all the new parts of the car to the base abstract class. I need not explain why this approach was taken, as there can be no car without an engine, wheel etc. The abstract “Car” will form the base for all other Car classes. The class diagram with the inheritance is shown below.
One can see there is no change to the hierarchy other than the introduction of new properties. Next we can have a look at the different parts needed for the car. First we will see the wheel. The class diagram for wheel is shown below.
As one can see from the above diagram the base for wheel is an interface called IWheel. IWheel is inherited to the respective car’ wheel class, in the above case, it is inherited to HyundaiWheel class. From the “HyundaiWheel” the different model’ wheel has been extended. The code for the above implementation is pasted below.
class HyundaiWheel : IWheel
class SantroWheel : HyundaiWheel
class i10Wheel : HyundaiWheel
class i20Wheel : HyundaiWheel
class SonataWheel : HyundaiWheel
class AccentWheel : HyundaiWheel
The above code is self explanatory. Next CD created engine. Here also the same concept is followed. An interface called IEngine which is implemented by the respective brand’ engine i.e. ToyotaEngine. ToyotaEngine is extended to implement the car specific engine like CamryEngine and CorollaEngine for Camry and Corolla models respectively. Why we have an interface for the engine is that every brand will have its own way of designing the engine, with interface we can give the freedom and also keep the contract in tact. Why we have a common class, ToyotaEngine, is that each brand will have there own common set of feature. The IEngine interface acts as the base for all the other cars engine. Honda implements IEngine to HondaEngine base class and then extends it to CityEngine, CivicEngine and AccordEngine. Similarly every brand follows the same concept.
The chassis also follows the same concept of an interface; interface implemented to a base class and then the base class is extended to create other model specific chassis.
Now this is an overkill of example I know but just to complete the car we need an axle also. The same concept is applied here also. I will not go into the details. CD has completed all the base classes needed for the abstract factory, now he has built the factories which will create these products.
The factory will have a base factory which again can be an interface or an abstract class and from this the other factories will implement/inherit the features. As CD already had an interface he decided to modify the “ICarFactory” interface used in the first implementation of abstract factory. To the “ICarFactory” he introduced four more methods to create the car engine (CreateEngine), to create car axle (CreateAxle), to create car chassis (CreateChassis) and finally to create wheel he incorporated “CreateWheel” method. After making changes to the interface CD implemented the interface to the car manufacturing factories. Few factories with the interface implementation are shown below.
As you can see the factories, HondaCivicFactory, FordFiestaFactory, HondaCityFactory and FordIkonFactory are implementing the interface ICarFactory. Similar to this all factories for the various models will implement the interface. The sample code for “FordFiestafactory” is shown below.
Next CD needed an assembling unit where the cars can be assembled. So CD created an “AssemblyFloor” class where cars can be assembled based on the dynamic factory passed. The AssemblyFloor code is shown below.
public AssemblyFloor(ICarFactory theCarFactory)
public Car AssembleCar(string theCarName)
With the AssemblyFloor CD finished his basic requirement for the abstract factory pattern. CD created “ShowRoom” class to test the working of the abstract factory implementation. Pasted below is the code of the “ShowRoom” class.
After implementing the above abstract factory pattern CD took his notepad to jot down the following.
GOF definition of abstract factory:
“Provide an interface for creating families of related or dependent objects without specifying their concrete classes.”
What is the problem this pattern solves?
When you have set of related objects or dependent object then you go for Abstract Factory. As seen in the e.g. above we are creating related objects of car like engine, axle etc, so scenario similar to this can be solved using Abstract factory.
How it Solves the Problem?
To solve the problem we identify a set of related or dependent classes and provide a base class for these related classes to inherit. Then we define the Abstract Factory class and this class is inherited by concrete factories. The abstract factory class has the methods to create the related or dependent classes but the freedom is given to derive classes to implement their own ways of implementing the logic.
Participants of the Pattern.
Abstract Factory – in our e.g. the IcarFactory is the abstract factory.
Concrete Factory – FordFiestaFactory, FordIkonFactory, HondaCivicFactory etc are concrete factories
Abstract Product – Car, IWheel, IChassis, IEngine etc are e.g.
Product – Fiesta, Ikon, i10, i20, Camry, Corolla etc are e.gs.
Client – Assembly floor is the client.
Real time e.g.
In .NET factory is implemented in page life cycle where “PageHandlerFactory” is used to create an ASP.NET page handler dynamically to process ASP.NET page requests. Other factory implementation in .net are “WebServiceHandlerFactory”, “SimpleHandlerFactory”, “HttpRemotingHandlerFactory” to handle, webservice, simple handlers, remoting requests respectively. Also you can find the implementation of factory in WebRequest class’ Create method, AppDomain’ CreateDomain method et all.
So with this CD was clear on Abstract Factory pattern and I hope the same is the case with the reader' of this blog.
In the next blog we will see the difference, CD found out between Factory and Abstract Factory pattern.