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
April 11, 2021

Hi, I just want to provide a constructive criticism about the example. Actually, this is an example of Factory Method implementations.

- Gabriel Armburu

    JournalDev
    DigitalOcean Employee
    DigitalOcean Employee badge
    August 25, 2020

    I would suggest to have one factory for computer and other factory for some other component and have an abstract factory as a whole for computer factory and some other factory., that way you will create abstract factory of factories and thus computer will become an interface with multiple computer implementations and the other factory with the same way. having a factory for every single concrete implementation of computer is not a good idea and it will not be a good example to project abstract factory.

    - vish

      JournalDev
      DigitalOcean Employee
      DigitalOcean Employee badge
      November 29, 2019

      If the concrete classes ‘PC’ & ‘Server’ have the same set of properties as the abstract class ‘Computer’, why not to have these properties defined in the ‘Computer’ class instead, along with the corresponding getters?

      - Vikram Sherigar

        JournalDev
        DigitalOcean Employee
        DigitalOcean Employee badge
        November 11, 2019

        Can you please explain more on Abstraction in case of Factory as well as Abstract Factory. I am not able to see the abstraction as the client still needs to know what to instantiate and what parameters to pass to instantiate the required class.

        - Suhas Nayak

          JournalDev
          DigitalOcean Employee
          DigitalOcean Employee badge
          June 30, 2019

          Your blog is very helpful :) Thanks!

          - AJ

            JournalDev
            DigitalOcean Employee
            DigitalOcean Employee badge
            July 30, 2018

            We can have some better example of abstract factory, need to improve AbastractFactory class

            - Umesh

              JournalDev
              DigitalOcean Employee
              DigitalOcean Employee badge
              July 14, 2018

              Hello, There is a small typo - “Banefits” Regards, Andrii

              - Andrii

                JournalDev
                DigitalOcean Employee
                DigitalOcean Employee badge
                March 30, 2018

                If in the end the user has to write new PCFactory() and new ServerFactory() then what is the use of creating all those interfaces. means instead of PCFactory and ServerFactory he could use new PC() and new Server()

                - Ashish Doneriya

                  JournalDev
                  DigitalOcean Employee
                  DigitalOcean Employee badge
                  February 26, 2018

                  good

                  - abc

                    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.