·
Abstract factory pattern is yet another creational
design pattern and is considered as another layer of abstraction over factory
pattern
·
Imagine if our car maker decide to go global. Becoming
global will require to enhance the system to support different car making
styles for different countries. For example we will consider USA, Asia and
default for all other countries.
·
First of all, we need car factories in each location specified
in problem statement. i.e. USACarFactory, AsiaCarFactory and DefaultCarFactory.
·
Now, our application should be smart enough to
identify the location where is being used, so we should be able to use appropriate
car factory without even knowing which car factory implementation will be used
internally. This also saves us from someone calling wrong factory for a
particular location.
·
So basically, we need another layer of abstraction which
will identify the location and internally use correct car factory
implementation without even giving a single hint to user. This is exactly the
problem, which abstract factory pattern is used to solve.
·
Let’s see how abstract factory solve above issue in
form of design:
Package Diagram
Sequence
Diagram
Implementation
in code
·
Lets write all separate car factories for different
locations. Begin with Car.java class
Car.java
public
abstract class Car {
public
Car(CarType model, Location location){
this.model
= model;
this.location
= location;
}
protected
abstract void construct();
private
CarType model = null;
private
Location location = null;
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;
}
}
·
This adds extra work of creating another enum for
storing different locations.
Location.java
public
enum Location {
DEFAULT,
USA, ASIA
}
· All car types will also have additional location
property. I am writing only for luxury car. Same follows for small and sedan
also.
}
LuxuryCar.java
public
class LuxuryCar extends Car
{
public
LuxuryCar(Location location)
{
super(CarType.LUXURY,
location);
construct();
}
@Override
protected
void construct() {
System.out.println(“luxury
car”);
//add
accessories
}
}
·
So for we have created basic classes. Now lets have
different car factories.
}
AsiaCarFactory.java
public
class AsiaCarFactory
{
public
static Car buildCar(CarType model)
{
Car
car = null;
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;
default:
//throw
some exception
break;
}
return
car;
}
}
DefaultCarFactory.java
public
class DefaultCarFactory
{
public
static Car buildCar(CarType model)
{
Car
car = null;
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;
default:
//throw
some exception
break;
}
return
car;
}
}
USACarFactory.java
public
class USACarFactory
{
public
static Car buildCar(CarType model)
{
Car
car = null;
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;
default:
//throw
some exception
break;
}
return
car;
}
}
·
Well, now we have all 3 different Car factories. Now,
we have to abstract the way these factories are accessed. Lets see how?
public class CarFactory
{
private
CarFactory() {
//Prevent
instantiation
}
public
static Car buildCar(CarType type)
{
Car
car = null;
Location
location = Location.ASIA; //Read location property somewhere from configuration
//Use
location specific car factory
switch(location)
{
case
USA:
car
= USACarFactory.buildCar(type);
break;
case
ASIA:
car
= AsiaCarFactory.buildCar(type);
break;
default:
car
= DefaultCarFactory.buildCar(type);
}
return
car;
}
}
- We are done with writing code. Now lets test what we have written till now.
public class TestFactoryPattern
{
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));
}
}
Output:
(Default location is Asia)
Building
small car
Model-
SMALL built in ASIA
Building
sedan car
Model-
SEDAN built in ASIA
Building
luxury car
Model- LUXURY built in ASIA
0 Comments:
Post a Comment