GoF Definition: Provides an interface for creating families of related or dependent objects without specifying their concrete classes.
In this pattern, we provide an encapsulation mechanism to a group of individual factories. These factories have a theme in common. In this process, an interface is used to create related objects. Here we do not call their implementer or concrete classes directly. We sometimes refer to this pattern as a factory of factories or a Super factory.
With this pattern, we can interchange the specific implementations without changing the user’s code. But to achieve this, we need to compensate for the complexity of the system. As a result, debugging may be difficult in many scenarios.
Suppose we are decorating our room. Now suppose we need two different types of almirah (or, say, table)—one must be made of wood and one of steel. For the wooden almirah, we need to visit a carpenter shop and for the other type, we can go to a readymade steel almirah shop. Both of these are almirah (or table) factories. Based on our demand, we decide what kind of factory we need. This scenario can be considered an example of this pattern.
ADO.NET has already implemented similar concepts to establish a connection to a database.
In this example, our client is looking for movies and he/she needs to access an Abstract Factory, IMovieFactory, and Abstract Products, ITollywoodMovie and IBollywoodMovie. The client does not care which of these factories is giving the concrete object for him/her. He/she uses only the generic interfaces of their products. The naming conventions are chosen for your easy reference.
High-level structure of the parts of the program is as follows:
package abstractfactory.pattern.demo;
interface ITollywoodMovie
{
String MovieName();
}
interface IBollywoodMovie
{
String MovieName();
}
interface IMovieFactory
{
ITollywoodMovie GetTollywoodMovie();
IBollywoodMovie GetBollywoodMovie();
}
//Tollywood Movie collections
class TollywoodActionMovie implements ITollywoodMovie
{
@Override
public String MovieName()
{
return "Kranti is a Tollywood Action Movie";
}
}
class TollywoodComedyMovie implements ITollywoodMovie
{
@Override
public String MovieName()
{
return "BasantaBilap is a Tollywood Comedy Movie";
}
}
// Bollywood Movie collections
class BollywoodActionMovie implements IBollywoodMovie
{
@Override
public String MovieName()
{
return "Bang Bang is a Bollywood Action Movie";
}
}
class BollywoodComedyMovie implements IBollywoodMovie
{
@Override
public String MovieName()
{
return "Munna Bhai MBBS is a Bollywood Comedy Movie";
}
}
//Action Movie Factory
class ActionMovieFactory implements IMovieFactory
{
public ITollywoodMovie GetTollywoodMovie()
{
return new TollywoodActionMovie();
}
public IBollywoodMovie GetBollywoodMovie()
{
return new BollywoodActionMovie();
}
}
//Comedy Movie Factory
class ComedyMovieFactory implements IMovieFactory
{
public ITollywoodMovie GetTollywoodMovie()
{
return new TollywoodComedyMovie();
}
public IBollywoodMovie GetBollywoodMovie()
{
return new BollywoodComedyMovie();
}
}
class AbstractFactoryPatternEx
{
public static void main(String[] args)
{
System.out.println("***Abstract Factory Pattern Demo***");
ActionMovieFactory actionMovies = new ActionMovieFactory();
ITollywoodMovie tAction = actionMovies.GetTollywoodMovie();
IBollywoodMovie bAction = actionMovies.GetBollywoodMovie();
System.out.println(" Action movies are:");
System.out.println(tAction.MovieName());
System.out.println(bAction.MovieName());
ComedyMovieFactory comedyMovies = new ComedyMovieFactory();
ITollywoodMovie tComedy = comedyMovies.GetTollywoodMovie();
IBollywoodMovie bComedy = comedyMovies.GetBollywoodMovie();
System.out.println(" Comedy movies are:");
System.out.println(tComedy.MovieName());
System.out.println(bComedy.MovieName());
}
}