Tutorial

Abstract Factory Design Pattern in Java

Published on August 3, 2022
author

Pankaj

Abstract Factory Design Pattern in Java

Welcome to Abstract Factory Design Pattern in java example. Abstract Factory design pattern is one of the Creational patterns. Abstract Factory pattern is almost similar to Factory Pattern except the fact that its more like factory of factories.

Abstract Factory

abstract factory, abstract factory design pattern, abstract factory pattern If you are familiar with factory design pattern in java, you will notice that we have a single Factory class. This factory class returns different subclasses based on the input provided and factory class uses if-else or switch statement to achieve this. In the Abstract Factory pattern, we get rid of if-else block and have a factory class for each sub-class. Then an Abstract Factory class that will return the sub-class based on the input factory class. At first, it seems confusing but once you see the implementation, it’s really easy to grasp and understand the minor difference between Factory and Abstract Factory pattern. Like our factory pattern post, we will use the same superclass and sub-classes.

Abstract Factory Design Pattern Super Class and Subclasses

Computer.java

package com.journaldev.design.model;
 
public 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();
    }
}

PC.java

package com.journaldev.design.model;
 
public 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;
    }
 
}

Server.java

package com.journaldev.design.model;
 
 
public 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;
    }
 
}

Factory Class for Each subclass

First of all we need to create a Abstract Factory interface or abstract class. ComputerAbstractFactory.java

package com.journaldev.design.abstractfactory;

import com.journaldev.design.model.Computer;

public interface ComputerAbstractFactory {

	public Computer createComputer();

}

Notice that createComputer() method is returning an instance of super class Computer. Now our factory classes will implement this interface and return their respective sub-class. PCFactory.java

package com.journaldev.design.abstractfactory;

import com.journaldev.design.model.Computer;
import com.journaldev.design.model.PC;

public 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);
	}

}

Similarly we will have a factory class for Server subclass. ServerFactory.java

package com.journaldev.design.abstractfactory;

import com.journaldev.design.model.Computer;
import com.journaldev.design.model.Server;

public 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);
	}

}

Now we will create a consumer class that will provide the entry point for the client classes to create sub-classes. ComputerFactory.java

package com.journaldev.design.abstractfactory;

import com.journaldev.design.model.Computer;

public class ComputerFactory {

	public static Computer getComputer(ComputerAbstractFactory factory){
		return factory.createComputer();
	}
}

Notice that its a simple class and getComputer method is accepting ComputerAbstractFactory argument and returning Computer object. At this point the implementation must be getting clear. Let’s write a simple test method and see how to use the abstract factory to get the instance of sub-classes. TestDesignPatterns.java

package com.journaldev.design.test;

import com.journaldev.design.abstractfactory.PCFactory;
import com.journaldev.design.abstractfactory.ServerFactory;
import com.journaldev.design.factory.ComputerFactory;
import com.journaldev.design.model.Computer;

public class TestDesignPatterns {

	public static void main(String[] args) {
		testAbstractFactory();
	}

	private static void testAbstractFactory() {
		Computer pc = com.journaldev.design.abstractfactory.ComputerFactory.getComputer(new PCFactory("2 GB","500 GB","2.4 GHz"));
		Computer server = com.journaldev.design.abstractfactory.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);
	}
}

Output of the above program will be:

AbstractFactory PC Config::RAM= 2 GB, HDD=500 GB, CPU=2.4 GHz
AbstractFactory Server Config::RAM= 16 GB, HDD=1 TB, CPU=2.9 GHz

Here is the class diagram of abstract factory design pattern implementation. Abstract Factory Pattern

Abstract Factory Design Pattern Benefits

  • Abstract Factory design pattern provides approach to code for interface rather than implementation.
  • Abstract Factory pattern is “factory of factories” and can be easily extended to accommodate more products, for example we can add another sub-class Laptop and a factory LaptopFactory.
  • Abstract Factory pattern is robust and avoid conditional logic of Factory pattern.

Abstract Factory Design Pattern Examples in JDK

  • javax.xml.parsers.DocumentBuilderFactory#newInstance()
  • javax.xml.transform.TransformerFactory#newInstance()
  • javax.xml.xpath.XPathFactory#newInstance()

Abstract Factory Design Pattern Video Tutorial

I recently uploaded a video on YouTube for abstract factory design pattern. In the video, I discuss when and how to implement an abstract factory pattern. I have also discussed what is the difference between the factory pattern and abstract factory design pattern. https://youtu.be/BPkYkyVWOaw

You can download the examples code from my GitHub Project.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors
Default avatar
Pankaj

author

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
JournalDev
DigitalOcean Employee
DigitalOcean Employee badge
July 8, 2013

Hi, Is there any pdf file available for all these design patters? Regards, Praveen

- Praveen

    JournalDev
    DigitalOcean Employee
    DigitalOcean Employee badge
    January 16, 2014

    One thing is nagging me in your example. Your factory should be without parameters and creatComputer should accept the parameters, currently multile calls to createComputer will create same computer instead of ones with different configuration. Existing methods: public ServerFactory(String ram, String hdd, String cpu){ public Computer createComputer() { Should be changed to these methods with following signature. public ServerFactory() public Computer createComputer(String ram, String hdd, String cpu) Factory should be without parameters and createComputer should accept parameters.

    - Vishwas

      JournalDev
      DigitalOcean Employee
      DigitalOcean Employee badge
      June 7, 2014

      Hi Pankaj, I am not able to understand Abstract Factory Design Pattern perfectly.Can you please help me ?? In ComputerFactory class, getComputer() method is taking ComputerAbstractFactory as argument.Are you sure this is correct ?? In your client program i.e. TestDesignPatterns.java, To create pc, the code is " Computer pc = com.journaldev.design.abstractfactory.ComputerFactory.getComputer(new PCFactory(“2 GB”,“500 GB”,“2.4 GHz”));". It means client have access to class PCFactory. When client has access to class PCFactory, then pc can be created without using ComputerFactory class. PCFactory factory = new PCFactory(“2 GB”,“500 GB”,“2.4 GHz”); Computer pc = factory.createComputer(); What is the use of ComputerFactory class when client have direct access to PCFactory or ServerFactory??? Best Regards, Badri

      - Badri

        JournalDev
        DigitalOcean Employee
        DigitalOcean Employee badge
        September 18, 2015

        clean explanation sir .can u provide pdf tutorial sir

        - bala

          JournalDev
          DigitalOcean Employee
          DigitalOcean Employee badge
          April 15, 2016

          I do not feel the If - else logic is actually irradicated. Sorry, to spoil the fun. When i first read it, I felt at last something that explains a difference between Factory and abstract factory. The if-else is removed from the Factory code as in other examples you find here and many other link https://www.tutorialspoint.com/design\_pattern/abstract\_factory\_pattern.htm. The if-else logic is still present in the factory class. However, this seems to b worse. Actually the responsibility has shifted to client side. Imagine, at compile time you do not what the client requests and the code would look like. String computerType= getRequestFromClient(); Computer remoteComputer = null; //Now this is where the actual if else comes in. if(computerType.equals(“PC”)){ remoteComputer = ComputerFactory.getComputer(new PCFactory(“2 GB”,“500 GB”,“2.4 GHz”)); } else if(computerType.equals(“SERVER”)){ remoteComputer = ComputerFactory.getComputer(new ServerFactory(“16 GB”,“1 TB”,“2.9 GHz”)) } //And remember this code block would be present everywhere you want the remoteComputer object from the factory… This was the reason why this code was moved to Factory to not let client worry about it… Else why to go with so much of Fuzz just type in: if(computerType.equals(“PC”)){ remoteComputer = new PCFactory(“2 GB”,“500 GB”,“2.4 GHz”); } else if(computerType.equals(“SERVER”)){ remoteComputer = new Server(“16 GB”,“1 TB”,“2.9 GHz”)) } //This looks much cleaner. This is why I feel som many people are confused with Design patterns because everyone just explain the way they like it.

          - Vinay Kallat

            JournalDev
            DigitalOcean Employee
            DigitalOcean Employee badge
            January 20, 2017

            Good Article. But if you aren’t still convinced why this pattern is to be used, we can refer to another example. Say you are writing application code independent of OS . Like Google Chrome Code. Now there will be a factory class for Windows OS to generate Windows Buttons, Menus etc. Similarly there will be another factory class for Linux OS to generate its buttons, menus. Now application code instead of coding to any of these factory classes will code to its interface - AbstractFactoryClass for simplicity This class is used more than to prevent if/else in factory pattern

            - Rajesh KSV

              JournalDev
              DigitalOcean Employee
              DigitalOcean Employee badge
              March 17, 2017

              This is no correct abstract factory implementation, here client knows about the concrete factories and just passing to consumer. Client shouldn’t know about concrete factories or concrete computer implementations. Abstract factory only should know the actual concrete factories to be used.

              - Kailash Singh

                JournalDev
                DigitalOcean Employee
                DigitalOcean Employee badge
                March 27, 2017

                Hi Pankaj. A question. In your TestDesignPatterns , it looks like the client directly knows about PCFactory and ServerFactory. Is this correct? Isn’t this a kind of coupling between the client and the factory classes?

                - Valentino

                  JournalDev
                  DigitalOcean Employee
                  DigitalOcean Employee badge
                  June 21, 2017

                  I think it is worth to add one more abstract product and bunch of end products which extends this one (two sets of products). Than it makes sens. https://en.wikipedia.org/wiki/Abstract\_factory\_pattern#/media/File:Abstract\_factory\_UML.svg

                  - Jacek Feliksiak

                    JournalDev
                    DigitalOcean Employee
                    DigitalOcean Employee badge
                    December 8, 2017

                    Your article and your example is very good and useful. I used some your example on my blog: https://stackjava.com and I place back link to your page. Because my students can not read english language… Please let me know if you feel bothered I will remove it. Thanks!

                    - kai

                      Try DigitalOcean for free

                      Click below to sign up and get $200 of credit to try our products over 60 days!

                      Sign up

                      Join the Tech Talk
                      Success! Thank you! Please check your email for further details.

                      Please complete your information!

                      Become a contributor for community

                      Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

                      DigitalOcean Documentation

                      Full documentation for every DigitalOcean product.

                      Resources for startups and SMBs

                      The Wave has everything you need to know about building a business, from raising funding to marketing your product.

                      Get our newsletter

                      Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

                      New accounts only. By submitting your email you agree to our Privacy Policy

                      The developer cloud

                      Scale up as you grow — whether you're running one virtual machine or ten thousand.

                      Get started for free

                      Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

                      *This promotional offer applies to new accounts only.