Abstract Factory ( Creational Design Pattern )
The abstract factory pattern is a software creational design pattern that provides a way to encapsulate a group of individual factories that have a common theme without specifying their concrete classes. or in similar way we can say as
The Abstract Factory design pattern (part of the Gang of Four) falls under the Creational design pattern category and it provides a way to encapsulate a group of factories that have a common link without highlighting their concrete classes.
This is all about a factory creating various objects at run time based on user demand. The client remains completely unaware (decoupled) on which concrete products it gets from each of these individual factories and the client is only able to access a simplified interface.
The essence of the Abstract Factory Pattern is to "Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
As intent of any Creational design pattern is to avoid using of "new" operator
Running Example
1) Let's assume we are startup company who want to manufacture different types of cars . We have below 3 types of cars in the production unit.
We have created enum of those types
We have different locations all over the globe where we want to open franchise
Let's define abstract class for all cars and then we can construct each type as per specific requirement .
OK , so now we have abstract class where we have taken help from mechanical engineer team and define basic parameters .
Now we are standing in production unit where we can actually "construct" car as per design approved by team.
Here we go with Small Car where we are just putting system out to display we are constructing car.
Now we have some experience of constructing small car , now lets do some thing more :)
Let's construct luxury car
We have all 3 model's developed . Now we can go for constructing the Factory for those
Alternative approach for design pattern
1) Sometimes creational patterns are competitors: there are cases when either Prototype or Abstract Factory could be used profitably. At other times they are complementary: Abstract Factory might store a set of Prototypes from which to clone and return product objects, Builder can use one of the other patterns to implement which components get built. Abstract Factory, Builder, and Prototype can use Singleton in their implementation.
Keep in Mind
The abstract factory pattern is a software creational design pattern that provides a way to encapsulate a group of individual factories that have a common theme without specifying their concrete classes. or in similar way we can say as
The Abstract Factory design pattern (part of the Gang of Four) falls under the Creational design pattern category and it provides a way to encapsulate a group of factories that have a common link without highlighting their concrete classes.
This is all about a factory creating various objects at run time based on user demand. The client remains completely unaware (decoupled) on which concrete products it gets from each of these individual factories and the client is only able to access a simplified interface.
The essence of the Abstract Factory Pattern is to "Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
As intent of any Creational design pattern is to avoid using of "new" operator
Abstract
Factory patterns works around a super-factory which creates
other factories. This factory is also called as Factory of factories. In Abstract Factory pattern an interface
is responsible for creating a factory of related objects, without explicitly
specifying their classes. This pattern is one level of abstraction higher than
factory pattern.
As there is a word ‘abstract’ in the pattern name
don’t mistake and confuse it with java ‘abstract’ keyword . It considered as another layer of abstraction
over factory
pattern.
e.g. In Java while doing XML work with DOM Parser , we
have used DocumentBuilderFactory class which is an example
abstract factory design pattern because it returns a factory called DocumentBuilder which then used to
create Document.
//Example of Abstract
Factory and Factory design pattern in Java
DocumentBuilderFactory abstractFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder factory = abstractFactory.newDocumentBuilder();
Document doc = factory.parse(stocks)
DocumentBuilderFactory abstractFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder factory = abstractFactory.newDocumentBuilder();
Document doc = factory.parse(stocks)
In this example DocumentBuilderFactory (Abstract
Factory) creates DocumentBuilder (Factory) which creates Documents (Products).
In normal
usage, the client software creates a concrete implementation of the
abstract factory and then uses the generic interfaces to create the
concrete objects that are part of the theme. The client does not know
(or care) which concrete objects it gets from each of these internal
factories, since it uses only the generic interfaces of their
products. This pattern separates the details of implementation of a set
of objects from their general usage and relies on object composition, as
object creation is implemented in methods exposed in the factory
interface
Example : The best
example will be configuring Database connection factory which hide
underline Database type. We can configure Oracle, DB2 or Sybase
Connection Factory in application.
1) java.util.Calendar#getInstance()
2) java.text.NumberFormat#getInstance()
Running Example
1) Let's assume we are startup company who want to manufacture different types of cars . We have below 3 types of cars in the production unit.
We have created enum of those types
public enum CarType {
SMALL, SEDAN, LUXURY
}
We have different locations all over the globe where we want to open franchise
public enum Location {
INDIA , USA , DEFAULT , EUROPE , ASIA
}
Let's define abstract class for all cars and then we can construct each type as per specific requirement .
public abstract class Car {
private CarType model = null;
private Location location = null;
public Car(CarType
model, Location location){
this.model = model;
this.location = location;
}
protected abstract
void construct();
public CarType
getModel() {
return model;
}
public void
setModel(CarType model) {
this.model = model;
}
public Location
getLocation() {
return location;
}
public void setLocation(Location
location) {
this.location = location;
}
@Override
public String
toString() {
return "Model-
"+model + " built in "+location;
}
}
OK , so now we have abstract class where we have taken help from mechanical engineer team and define basic parameters .
Now we are standing in production unit where we can actually "construct" car as per design approved by team.
Here we go with Small Car where we are just putting system out to display we are constructing car.
public class SmallCar extends Car{
public
SmallCar(Location location){
super(CarType.SMALL, location);
}
@Override
protected
void construct() {
System.out.println("Building
SMALL car");
}
}
Now we have some experience of constructing small car , now lets do some thing more :)
public class SedanCar extends Car{
public
SedanCar(Location location){
super(CarType.SEDAN, location);
}
@Override
protected void construct() {
System.out.println("Building SEDAN
car");
}
}
Let's construct luxury car
public class LuxuryCar extends Car{
public
LuxuryCar(Location location){
super(CarType.LUXURY, location);
}
@Override
protected void construct() {
System.out.println("Building luxury car");
}
}
We have all 3 model's developed . Now we can go for constructing the Factory for those
1) public class
DefaultCarFactory {
Car
car = null;
public static Car
buildCar(CarType model){
switch (model){
case SMALL:
car
= new
SmallCar(Location.DEFAULT);
break;
case SEDAN:
car
= new
SedanCar(Location.DEFAULT);
break;
case LUXURY:
car
= new
LuxuryCar(Location.DEFAULT);
break;
}
return car;
}
}
2) public class AsiaCarFactory
{
Car
car = null;
public static Car
buildCar(CarType model){
switch (model){
case SMALL:
car
= new
SmallCar(Location.ASIA); break;
case SEDAN:
car
= new
SedanCar(Location.ASIA); break;
case LUXURY:
car
= new LuxuryCar(Location.ASIA); break;
}
return car;
}}
3) public class USACarFactory {
Car
car = null;
public static Car buildCar(CarType
model){
switch (model){
case SMALL:
car
= new
SmallCar(Location.USA); break;
case SEDAN:
car
= new
SedanCar(Location.USA); break;
case LUXURY:
car
= new
LuxuryCar(Location.USA); break;
}
return car;
}
}
Here the heart of our factory is CarFactory
public class CarFactory {
private CarFactory() { }
public static Car
buildCar(CarType type)
{
Car
car = null;
Location
location = Location.ASIA;
switch(location)
{
case USA:
car
= USACarFactory.buildCar(type); break;
case ASIA:
car = AsiaCarFactory.buildCar(type); break;
case DEFAULT:
car
= DefaultCarFactory.buildCar(type); break;
}
return car;
}
}
All things done , now lets give franchises and earn some money :)
public class TestFactoryPattern {
/**
* @param args
*/
public static void main(String[]
args) {
System.out.println(CarFactory.buildCar(CarType.SMALL));
System.out.println(CarFactory.buildCar(CarType.SEDAN));
System.out.println(CarFactory.buildCar(CarType.LUXURY));
}
}
Abstract Factories are great for supporting
multiple platforms while keeping your code-base unified. Suppose you
have a large Qt or GTK+ or .NET/Mono program that you want to run on
Windows, Linux, and OSX. But you have a feature that is implemented in a
different way on each platform (perhaps via the kernel32 API or a POSIX
feature).
public abstract class Feature
{
public abstract int PlatformSpecificValue { get; }
public static Feature PlatformFeature
{
get
{
string platform;
// do platform detection here
if (platform == "Win32")
return new Win32Feature();
if (platform == "POSIX")
return new POSIXFeature();
}
}
// platform overrides omitted
}
With this Abstract Factory, your UI doesn't need to know anything about the current platform.Feature feature = Feature.PlatformFeature;
Console.WriteLine(feature.PlatformSpecificValue);
Alternative approach for design pattern
1) Sometimes creational patterns are competitors: there are cases when either Prototype or Abstract Factory could be used profitably. At other times they are complementary: Abstract Factory might store a set of Prototypes from which to clone and return product objects, Builder can use one of the other patterns to implement which components get built. Abstract Factory, Builder, and Prototype can use Singleton in their implementation.
2) Abstract Factory can be used as an alternative to Façade pattern to hide platform specific classes
3) AbstractFactory class declares only an interface for creating the products. The actual creation is the task of the ConcreteProduct classes, where a good approach is applying the Factory Method design pattern for each product of the family.
4) Abstract Factory classes are often implemented with Factory Methods, but they can also be implemented using Prototype.
3) AbstractFactory class declares only an interface for creating the products. The actual creation is the task of the ConcreteProduct classes, where a good approach is applying the Factory Method design pattern for each product of the family.
4) Abstract Factory classes are often implemented with Factory Methods, but they can also be implemented using Prototype.
Most Discussion question in universe of design pattern :)
Difference between Abstract Factory and Factory Method pattern:
- Factory Method pattern exposes a method to the client for creating the object whereas in case of Abstract Factory they expose a family of related objects which may consist of these Factory methods.
- Designs start out using Factory Method (less complicated, more customizable, subclasses proliferate) and evolve toward Abstract Factory, Prototype, or Builder (more flexible, more complex) as the designer discovers where more flexibility is needed.
- Factory Method pattern hides the construction of single object where as abstract factory method hides the construction of a family of related objects. Abstract factories are usually implemented using (a set of) factory methods.
Keep in Mind
progress
No comments:
Post a Comment