Abstract Factory Design Pattern is another flavour of Factory Design Pattern.
This pattern can be considered as a “super factory” or “Factory of factories”.
The Abstract Factory design pattern is a creational pattern that provides an interface for creating families of related or dependent objects without specifying their concrete classes. This pattern allows you to produce objects that belong to a particular family, ensuring that the objects are compatible with each other and conform to a specific set of interfaces or classes.
Problem Statement:
For example, consider a garments factory specialized in creating trousers and
shirts. Now the Parent company which is a famous Retail brand is now venturing
into Gadget section. They are also planning to expand their Factories having
one center in US and another one in UK. The client should be completely unaware
of how the objects are created. What is the best design pattern we can use to
resolve this requirement?
Solution:
To solve the above design problem we will use Abstract Factory Pattern. As
mentioned earlier this is the super Factory. The above problem cannot be
resolved efficiently using the Factory method pattern as this involves multiple
Factories and products which are related to the parent company or dependent.
Now let’s have a look at our real life Garment Factory example
and what’s the difference than the Factory Method pattern.
Example:
In the above real life example,
the RetailFactory is AbstractFactory class which now has multiple Concrete
factories (UKFactory and USFactory) in various locations like US and UK
specialized in creating multiple products like Shirt/Laptop and Trouser/Mobile
respectively. In this example we have also created another additional class
called FactoryMaker which takes the choice of Factory from the client and then
delegates the job to appropriate Factory classes accordingly. The client is
completely unaware of how this processing is done and has reference to only the
RetailFactory interface and GarmentType and GadgetType interface. This loose
coupling also helps in terms of addition of multiple Concrete Products without
much change in the client code.
Benefits:
Use of this pattern makes it possible to interchange the concrete classes
without changing the client code even at run time.
Here are several real-time use cases for the Abstract Factory Method
pattern:
1. Database Access Layers
Context: Applications that support multiple database
systems (e.g., MySQL, PostgreSQL, Oracle) need a way to create database
connections and queries that are specific to each database type.
Example: A data access layer uses the Abstract Factory
Method pattern to create different sets of database connections and query
objects based on the database system being used.
2. Document Generation Systems
Context: Document generation systems that produce different
types of documents (e.g., PDF, Word, HTML) need a way to handle different
document formats and their components.
Example: A document generation system uses the Abstract
Factory Method pattern to create documents and pages specific to each format.
3. Automotive Manufacturing
Context: In automotive manufacturing, different types of
vehicles (e.g., sedans, SUVs) require different sets of components (e.g.,
engines, tires, interiors).
Example: An automotive factory uses the Abstract Factory
Method pattern to create different sets of components for each vehicle type.
Source code for Abstract Factory
example:
GarmentType.java
/**
*
@author TeachtoJava
*
*/
public interface GarmentType {
String
print();
}
GadgetType.java
public interface GadgetType {
String
print();
}
RetailFactory.java
/**
*
Factory class is the abstract class which will
* be referred by client. All the concrete
classes needs to
* implement the abstract factory method.
*
@author TeachtoJava
*/
public interface RetailFactory {
GarmentType createGarments(String garmentSelection);
GadgetType createGadgets(String gadgetSelection);
}
Shirt.java
public class Shirt implements GarmentType {
@Override
public
String print() {
System.out.println("Shirt
Created");
return
"Shirt";
}
}
Trouser.java
public class Trouser implements GarmentType {
@Override
public
String print() {
System.out.println("Trouser
Created");
return
"Trouser";
}
}
Laptop.java
public class Laptop implements GadgetType {
@Override
public
String print() {
System.out.println("Laptop
Created");
return
"Laptop";
}
}
Mobile.java
public class Mobile implements GadgetType {
@Override
public
String print() {
System.out.println("Mobile
Created");
return
"Mobile";
}
}
UKFactory.java
public class UKFactory implements
RetailFactory{
public GarmentType createGarments(String
garmentSelection) {
if
(garmentSelection.equalsIgnoreCase("Trouser")) {
return
new Trouser();
}
throw
new IllegalArgumentException("Selection doesnot exist");
}
public
GadgetType createGadgets(String gadgetSelection) {
if
(gadgetSelection.equalsIgnoreCase("Mobile")) {
return
new Mobile();
}
throw
new IllegalArgumentException("Selection doesnot exist");
}
}
USFactory.java
public class USFactory implements
RetailFactory{
public
GarmentType createGarments(String garmentSelection) {
if
(garmentSelection.equalsIgnoreCase("Shirt")) {
return
new Shirt();
}
throw
new IllegalArgumentException("Selection doesnot exist");
}
public
GadgetType createGadgets(String gadgetSelection) {
if
(gadgetSelection.equalsIgnoreCase("Laptop")) {
return
new Laptop();
}
throw
new IllegalArgumentException("Selection doesnot exist");
}
}
FactoryMaker.java
public class FactoryMaker {
private
static RetailFactory abstractFactory = null;
static
RetailFactory getFactory(String choice){
if(choice.equalsIgnoreCase("UK")){
abstractFactory
= new UKFactory();
}
else if(choice.equalsIgnoreCase("US")){
abstractFactory
= new USFactory();
}
return
abstractFactory;
}
}
Client.java
public class Client {
public
static void main(String[] args) {
BufferedReader
br = new BufferedReader(new InputStreamReader(System.in));
String
garmentSelection = null;
String
gadgetSelection = null;
String
countryChoice = null;
try
{
System.out.println("1.
Enter your selection from Trouser/Shirt:\n");
garmentSelection
= br.readLine();
System.out.println("2.
Enter your selection from Laptop/Mobile:\n");
gadgetSelection
= br.readLine();
System.out.println("3.
Enter your Country Selection from UK/US:\n");
countryChoice
= br.readLine();
}
catch (IOException e) {
e.printStackTrace();
}
RetailFactory
objRetailFactory = FactoryMaker.getFactory(countryChoice);
System.out.println("Your
choice of country is " + countryChoice);
GarmentType
objGarmentType = objRetailFactory.createGarments(garmentSelection);
System.out.println(objGarmentType.print());
GadgetType
objGadgetType = objRetailFactory.createGadgets(gadgetSelection);
System.out.println(objGadgetType.print());
}
}
No comments:
Post a Comment