Abstract factory pattern in java

Spread the words...Share on Google+4Share on Facebook6Tweet about this on Twitter3Share on LinkedIn4Buffer this pageShare on StumbleUpon37Share on Reddit0

Abstract factory pattern is yet another creational design pattern and is considered as another layer of abstraction over factory pattern. In this post, i will expand the problem statement discussed in previous post and will see, how abstract factory pattern solve the problem.

In my previous post, “Implementing factory design pattern in java“, we discussed how to abstract the car making process for various car model types and their additional logic included in car making process. Lets expand this use case. Now, 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.

Sections in this post:

  • Designing global car factory
  • Implementation in code
  • Final notes

Designing global car factory

In factory pattern implementation, we designed a factory which was suitable for a single location. Supporting multiple locations will need critical design changes.

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.

Lets see how abstract factory solve above issue in form of design:

Package Diagram

Abstract fctory design parttern package diagram

Sequence Diagram

abstract factory design pattern sequence diagram

Implementation in code

So, we are ready to write the implementation. Lets hit the keyboard.

Lets write all separate car factories for different locations. Begin with modifying our Car.java class with another attribute: location.

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 cat 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("Building 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

Final notes

We already have seen the use case scenarios of Factory pattern so whenever you need another level of abstraction over a group of factories, you should consider using abstract factory pattern./

You can already look deeper in different implementations of abstract factory in JDK distribution:

There are other similar examples but the need is to have the feel of abstract factory, which you must have got till now.

Happy Learning!!

Spread the words...Share on Google+4Share on Facebook6Tweet about this on Twitter3Share on LinkedIn4Buffer this pageShare on StumbleUpon37Share on Reddit0

Give me your email address and whenever I write any tutorial or discuss any java concept, you will receive a little email in your inbox.

Join 2,850 other subscribers

4 thoughts on “Abstract factory pattern in java”

  1. Thanks for the article.Its explained well using the example of car.Now I need a real time scenario where this pattern is used(like factory is used in SessionFactory in hibernate)

Leave a Reply