Abstract Factory:
Define aninterface orabstractclass forcreatingfamiliesof related(ordependent)objectsbutwithout
specifyingtheirconcrete sub-classes.ThatmeansAbstractFactoryletsa class returnsa factoryof
classes.Thisfactoryisalso calledas factoryof factories
Abstract factory pattern, where you find a factory (or builder) for a specific type of object, and
then this factory gives you a concrete instance of that object.
ImplementationApproach1:
1) Define the Abstractclasswhichwill extendorimplementbythe concrete class.
2) Implementthe concrete class.
3) Define the AbstractFactorywhichwill extendorimplementbythe concrete Factory class.The Return
type of the Abstractfactory isabstract classtype.
4) Implementthe concrete factory.
5) Create the Factory Producer. ReturnType of this is Abstract Factory type andthe Inputparameter
.Basedon the inputparametercreatesthe concrete factoryandreturnit.
6) In clientcode, Call the FactoryProducerWiththe inputparameter.Thiswill returnthe corresponding
concrete factoryand assignitto the AbstractFactory type.Soif you dothe actionsthenthe
correspondingconcrete classwillgetcalled.
ImplementationApproach2:
1) Define the Abstractclasswhichwill extendorimplementbythe concrete class.
2) Implementthe concrete class.
3) Define the Abstract Factorywhichwill extendorimplementbythe concrete Factory class.The Return
type of the Abstractfactory isabstract classtype.
4) Implementthe concrete factory.
5) Create the Factory Producer. ReturnType of this is Abstract class type and the Inputparameteris
abstract factory type.Based on the inputparametercreate the concrete factoryand returnit.
6) In clientcode, call the FactoryProducerWiththe inputparameterascorresponding factory.
Difference betweenfirstandsecondapproach.
In Approach 1, inside the factory producer,the if - else conditionrequiredtocheckthe inputparameter
and basedonthisthe concrete factoryiscreating.
In Approach 2, callingthe factoryproducertime itself we are passingthe concrete factory.
Benefits of Abstract Factory Pattern:
AbstractFactory patternprovidesapproachtocode forinterface ratherthanimplementation.
AbstractFactory patternis “factoryof factories”andcan be easily extendedtoaccommodate more
products,forexample we can add anothersub-classLaptopanda factory LaptopFactory.
AbstractFactory patternis robustand avoidconditional logicof Factorypattern.
Abstract Factory Pattern Examples in JDK.
 javax.xml.parsers.DocumentBuilderFactory#newInstance()
 javax.xml.transform.TransformerFactory#newInstance()
 javax.xml.xpath.XPathFactory#newInstance().
Example Program for Approach 1:
abstract class Animal {
public abstract String makeSound();
}
class Cat extends Animal {
public String makeSound() {
return "Mee";
}
}
class Dog extends Animal {
public String makeSound() {
return "Bark";
}
}
class Snake extends Animal {
public String makeSound() {
return "Hisss";
}
}
class Tyrannosaurus extends Animal {
@Override
public String makeSound() {
return "Roar";
}
}
abstract class SpeciesFactory {
public abstract Animal getAnimal(String type);
}
class MammalFactory extends SpeciesFactory {
@Override
public Animal getAnimal(String type) {
if ("dog".equals(type)) {
return new Dog();
} else {
return new Cat();
}
}
}
class ReptileFactory extends SpeciesFactory {
@Override
public Animal getAnimal(String type) {
if ("snake".equals(type)) {
return new Snake();
} else {
return new Tyrannosaurus();
}
}
}
class AbstractFactory {
public SpeciesFactory getSpeciesFactory(String type) {
if ("mammal".equals(type)) {
return new MammalFactory();
} else {
return new ReptileFactory();
}
}
}
public class AbstractFactoryDemo {
public static void main(String[] args) {
AbstractFactory abstractFactory = new AbstractFactory();
SpeciesFactory speciesFactory1 =
abstractFactory.getSpeciesFactory("reptile");
Animal a1 = speciesFactory1.getAnimal("tyrannosaurus");
System.out.println("a1 sound: " + a1.makeSound());
Animal a2 = speciesFactory1.getAnimal("snake");
System.out.println("a2 sound: " + a2.makeSound());
SpeciesFactory speciesFactory2 =
abstractFactory.getSpeciesFactory("mammal");
Animal a3 = speciesFactory2.getAnimal("dog");
System.out.println("a3 sound: " + a3.makeSound());
Animal a4 = speciesFactory2.getAnimal("cat");
System.out.println("a4 sound: " + a4.makeSound());
}
}
Example Program for Approach 2:
abstract class Computer {
public abstract String getRAM();
public abstract String getHDD();
public abstract String getCPU();
@Override
public String toString() {
return "RAM= " + this.getRAM() + ", HDD=" + this.getHDD() + ",CPU=" +
this.getCPU();
}
}
class PC extends Computer {
private String ram;
private String hdd;
private String cpu;
public PC(String ram, String hdd, String cpu) {
this.ram = ram;
this.hdd = hdd;
this.cpu = cpu;
}
@Override
public String getRAM() {
return this.ram;
}
@Override
public String getHDD() {
return this.hdd;
}
@Override
public String getCPU() {
return this.cpu;
}
}
class Server extends Computer {
private String ram;
private String hdd;
private String cpu;
public Server(String ram, String hdd, String cpu) {
this.ram = ram;
this.hdd = hdd;
this.cpu = cpu;
}
@Override
public String getRAM() {
return this.ram;
}
@Override
public String getHDD() {
return this.hdd;
}
@Override
public String getCPU() {
return this.cpu;
}
}
interface ComputerAbstractFactory {
public Computer createComputer();
}
class PCFactory implements ComputerAbstractFactory {
private String ram;
private String hdd;
private String cpu;
public PCFactory(String ram, String hdd, String cpu) {
this.ram = ram;
this.hdd = hdd;
this.cpu = cpu;
}
@Override
public Computer createComputer() {
return new PC(ram, hdd, cpu);
}
}
class ServerFactory implements ComputerAbstractFactory {
private String ram;
private String hdd;
private String cpu;
public ServerFactory(String ram, String hdd, String cpu) {
this.ram = ram;
this.hdd = hdd;
this.cpu = cpu;
}
@Override
public Computer createComputer() {
return new Server(ram, hdd, cpu);
}
}
class ComputerFactory {
public static Computer getComputer(ComputerAbstractFactory factory) {
return factory.createComputer();
}
}
public class TestDesignPatterns {
public static void main(String[] args) {
Computer pc = ComputerFactory.getComputer(new PCFactory("2 GB", "500
GB", "2.4 GHz"));
Computer server = ComputerFactory.getComputer(new ServerFactory("16 GB",
"1 TB", "2.9 GHz"));
System.out.println("AbstractFactory PC Config::" + pc);
System.out.println("AbstractFactory Server Config::" + server);
}
}
Abstract factory VS Builder Pattern:
Builder provides you more control over the object creation process .
Abstract factory VS Factory Pattern
With the Factory pattern, you produce implementations (Apple, Banana, Cherry, etc.) of a
particular interface -- say, IFruit.
With the Abstract Factory pattern, you produce implementations of a particular Factory interface
-- e.g., IFruitFactory. Each of those knows how to create different kinds of fruit.
Abstract factory VS Factory Method Pattern
Factory Method pattern uses inheritance and relies on a subclass to handle the desired object
instantiation.
Abstract Factory pattern, a class delegates the responsibility of object instantiation to another
object via composition...
The methods of an Abstract Factory are implemented as Factory Methods. Both the Abstract
Factory Pattern and the Factory Method Pattern decouples the client system from the actual
implementation classes through the abstract types and factories.
The Abstract Factory Pattern consists of an AbstractFactory, ConcreteFactory, AbstractProduct,
ConcreteProduct and Client.
How to implement
The Abstract Factory Pattern can be implemented using the Factory Method Pattern, Prototype
Pattern or the Singleton Pattern. The ConcreteFactory object can be implemented as a Singleton
as only one instance of the ConcreteFactory object is needed.
Factory Method pattern is a simplified version of Abstract Factory pattern. Factory Method
pattern is responsible of creating products that belong to one family, while Abstract Factory
pattern deals with multiple families of products.
Factory Method uses interfaces and abstract classes to decouple the client from the generator
class and the resulting products. Abstract Factory has a generator that is a container for several
factory methods, along with interfaces decoupling the client from the generator and the
products.
When to Use the Factory Method Pattern
Use the Factory Method pattern when there is a need to decouple a client from a particular
product that it uses. Use the Factory Method to relieve a client of responsibility for creating and
configuring instances of a product.
When to Use the Abstract Factory Pattern
Use the Abstract Factory pattern when clients must be decoupled from product classes.
Especially useful for program configuration and modification. The Abstract Factory pattern
can also enforce constraints about which classes must be used with others. It may be a lot of
work to make new concrete factories.

Abstract factory

  • 1.
    Abstract Factory: Define aninterfaceorabstractclass forcreatingfamiliesof related(ordependent)objectsbutwithout specifyingtheirconcrete sub-classes.ThatmeansAbstractFactoryletsa class returnsa factoryof classes.Thisfactoryisalso calledas factoryof factories Abstract factory pattern, where you find a factory (or builder) for a specific type of object, and then this factory gives you a concrete instance of that object. ImplementationApproach1: 1) Define the Abstractclasswhichwill extendorimplementbythe concrete class. 2) Implementthe concrete class. 3) Define the AbstractFactorywhichwill extendorimplementbythe concrete Factory class.The Return type of the Abstractfactory isabstract classtype. 4) Implementthe concrete factory. 5) Create the Factory Producer. ReturnType of this is Abstract Factory type andthe Inputparameter .Basedon the inputparametercreatesthe concrete factoryandreturnit. 6) In clientcode, Call the FactoryProducerWiththe inputparameter.Thiswill returnthe corresponding concrete factoryand assignitto the AbstractFactory type.Soif you dothe actionsthenthe correspondingconcrete classwillgetcalled. ImplementationApproach2: 1) Define the Abstractclasswhichwill extendorimplementbythe concrete class. 2) Implementthe concrete class. 3) Define the Abstract Factorywhichwill extendorimplementbythe concrete Factory class.The Return type of the Abstractfactory isabstract classtype. 4) Implementthe concrete factory. 5) Create the Factory Producer. ReturnType of this is Abstract class type and the Inputparameteris abstract factory type.Based on the inputparametercreate the concrete factoryand returnit. 6) In clientcode, call the FactoryProducerWiththe inputparameterascorresponding factory.
  • 2.
    Difference betweenfirstandsecondapproach. In Approach1, inside the factory producer,the if - else conditionrequiredtocheckthe inputparameter and basedonthisthe concrete factoryiscreating. In Approach 2, callingthe factoryproducertime itself we are passingthe concrete factory. Benefits of Abstract Factory Pattern: AbstractFactory patternprovidesapproachtocode forinterface ratherthanimplementation. AbstractFactory patternis “factoryof factories”andcan be easily extendedtoaccommodate more products,forexample we can add anothersub-classLaptopanda factory LaptopFactory. AbstractFactory patternis robustand avoidconditional logicof Factorypattern. Abstract Factory Pattern Examples in JDK.  javax.xml.parsers.DocumentBuilderFactory#newInstance()  javax.xml.transform.TransformerFactory#newInstance()  javax.xml.xpath.XPathFactory#newInstance(). Example Program for Approach 1: abstract class Animal { public abstract String makeSound(); } class Cat extends Animal { public String makeSound() { return "Mee"; } } class Dog extends Animal { public String makeSound() { return "Bark"; } } class Snake extends Animal { public String makeSound() { return "Hisss"; } } class Tyrannosaurus extends Animal {
  • 3.
    @Override public String makeSound(){ return "Roar"; } } abstract class SpeciesFactory { public abstract Animal getAnimal(String type); } class MammalFactory extends SpeciesFactory { @Override public Animal getAnimal(String type) { if ("dog".equals(type)) { return new Dog(); } else { return new Cat(); } } } class ReptileFactory extends SpeciesFactory { @Override public Animal getAnimal(String type) { if ("snake".equals(type)) { return new Snake(); } else { return new Tyrannosaurus(); } } } class AbstractFactory { public SpeciesFactory getSpeciesFactory(String type) { if ("mammal".equals(type)) { return new MammalFactory(); } else { return new ReptileFactory(); } } } public class AbstractFactoryDemo { public static void main(String[] args) { AbstractFactory abstractFactory = new AbstractFactory(); SpeciesFactory speciesFactory1 = abstractFactory.getSpeciesFactory("reptile"); Animal a1 = speciesFactory1.getAnimal("tyrannosaurus"); System.out.println("a1 sound: " + a1.makeSound()); Animal a2 = speciesFactory1.getAnimal("snake"); System.out.println("a2 sound: " + a2.makeSound());
  • 4.
    SpeciesFactory speciesFactory2 = abstractFactory.getSpeciesFactory("mammal"); Animala3 = speciesFactory2.getAnimal("dog"); System.out.println("a3 sound: " + a3.makeSound()); Animal a4 = speciesFactory2.getAnimal("cat"); System.out.println("a4 sound: " + a4.makeSound()); } } Example Program for Approach 2: abstract class Computer { public abstract String getRAM(); public abstract String getHDD(); public abstract String getCPU(); @Override public String toString() { return "RAM= " + this.getRAM() + ", HDD=" + this.getHDD() + ",CPU=" + this.getCPU(); } } class PC extends Computer { private String ram; private String hdd; private String cpu; public PC(String ram, String hdd, String cpu) { this.ram = ram; this.hdd = hdd; this.cpu = cpu; } @Override public String getRAM() { return this.ram; } @Override public String getHDD() { return this.hdd; } @Override public String getCPU() { return this.cpu; } }
  • 5.
    class Server extendsComputer { private String ram; private String hdd; private String cpu; public Server(String ram, String hdd, String cpu) { this.ram = ram; this.hdd = hdd; this.cpu = cpu; } @Override public String getRAM() { return this.ram; } @Override public String getHDD() { return this.hdd; } @Override public String getCPU() { return this.cpu; } } interface ComputerAbstractFactory { public Computer createComputer(); } class PCFactory implements ComputerAbstractFactory { private String ram; private String hdd; private String cpu; public PCFactory(String ram, String hdd, String cpu) { this.ram = ram; this.hdd = hdd; this.cpu = cpu; } @Override public Computer createComputer() { return new PC(ram, hdd, cpu); } } class ServerFactory implements ComputerAbstractFactory { private String ram; private String hdd; private String cpu; public ServerFactory(String ram, String hdd, String cpu) { this.ram = ram; this.hdd = hdd; this.cpu = cpu; }
  • 6.
    @Override public Computer createComputer(){ return new Server(ram, hdd, cpu); } } class ComputerFactory { public static Computer getComputer(ComputerAbstractFactory factory) { return factory.createComputer(); } } public class TestDesignPatterns { public static void main(String[] args) { Computer pc = ComputerFactory.getComputer(new PCFactory("2 GB", "500 GB", "2.4 GHz")); Computer server = ComputerFactory.getComputer(new ServerFactory("16 GB", "1 TB", "2.9 GHz")); System.out.println("AbstractFactory PC Config::" + pc); System.out.println("AbstractFactory Server Config::" + server); } } Abstract factory VS Builder Pattern: Builder provides you more control over the object creation process . Abstract factory VS Factory Pattern With the Factory pattern, you produce implementations (Apple, Banana, Cherry, etc.) of a particular interface -- say, IFruit. With the Abstract Factory pattern, you produce implementations of a particular Factory interface -- e.g., IFruitFactory. Each of those knows how to create different kinds of fruit.
  • 7.
    Abstract factory VSFactory Method Pattern Factory Method pattern uses inheritance and relies on a subclass to handle the desired object instantiation. Abstract Factory pattern, a class delegates the responsibility of object instantiation to another object via composition... The methods of an Abstract Factory are implemented as Factory Methods. Both the Abstract Factory Pattern and the Factory Method Pattern decouples the client system from the actual implementation classes through the abstract types and factories. The Abstract Factory Pattern consists of an AbstractFactory, ConcreteFactory, AbstractProduct, ConcreteProduct and Client. How to implement The Abstract Factory Pattern can be implemented using the Factory Method Pattern, Prototype Pattern or the Singleton Pattern. The ConcreteFactory object can be implemented as a Singleton as only one instance of the ConcreteFactory object is needed. Factory Method pattern is a simplified version of Abstract Factory pattern. Factory Method pattern is responsible of creating products that belong to one family, while Abstract Factory pattern deals with multiple families of products. Factory Method uses interfaces and abstract classes to decouple the client from the generator class and the resulting products. Abstract Factory has a generator that is a container for several factory methods, along with interfaces decoupling the client from the generator and the products. When to Use the Factory Method Pattern Use the Factory Method pattern when there is a need to decouple a client from a particular product that it uses. Use the Factory Method to relieve a client of responsibility for creating and configuring instances of a product. When to Use the Abstract Factory Pattern Use the Abstract Factory pattern when clients must be decoupled from product classes. Especially useful for program configuration and modification. The Abstract Factory pattern can also enforce constraints about which classes must be used with others. It may be a lot of work to make new concrete factories.