Welcome to the Factory Design Pattern in Java tutorial. Factory Pattern is one of the Creational Design pattern and it’s widely used in JDK as well as frameworks like Spring and Struts.
The factory design pattern is used when we have a superclass with multiple sub-classes and based on input, we need to return one of the sub-class. This pattern takes out the responsibility of the instantiation of a class from the client program to the factory class. Let’s first learn how to implement a factory design pattern in java and then we will look into factory pattern advantages. We will see some of the factory design pattern usage in JDK. Note that this pattern is also known as Factory Method Design Pattern.
Super class in factory design pattern can be an interface, abstract class or a normal java class. For our factory design pattern example, we have abstract super class with overridden toString()
method for testing purpose.
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();
}
}
Let’s say we have two sub-classes PC and Server with below implementation.
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;
}
}
Notice that both the classes are extending Computer
super class.
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;
}
}
Now that we have super classes and sub-classes ready, we can write our factory class. Here is the basic implementation.
package com.journaldev.design.factory;
import com.journaldev.design.model.Computer;
import com.journaldev.design.model.PC;
import com.journaldev.design.model.Server;
public class ComputerFactory {
public static Computer getComputer(String type, String ram, String hdd, String cpu){
if("PC".equalsIgnoreCase(type)) return new PC(ram, hdd, cpu);
else if("Server".equalsIgnoreCase(type)) return new Server(ram, hdd, cpu);
return null;
}
}
Some important points about Factory Design Pattern method are;
getComputer
is the factory method.Here is a simple test client program that uses above factory design pattern implementation.
package com.journaldev.design.test;
import com.journaldev.design.factory.ComputerFactory;
import com.journaldev.design.model.Computer;
public class TestFactory {
public static void main(String[] args) {
Computer pc = ComputerFactory.getComputer("pc","2 GB","500 GB","2.4 GHz");
Computer server = ComputerFactory.getComputer("server","16 GB","1 TB","2.9 GHz");
System.out.println("Factory PC Config::"+pc);
System.out.println("Factory Server Config::"+server);
}
}
Output of above program is:
Factory PC Config::RAM= 2 GB, HDD=500 GB, CPU=2.4 GHz
Factory Server Config::RAM= 16 GB, HDD=1 TB, CPU=2.9 GHz
getInstance()
methods uses Factory pattern.valueOf()
method in wrapper classes like Boolean, Integer etc.I recently uploaded a video on YouTube for Factory Design pattern, please check it out. Please like and share the video and subscribe to my YouTube channel. https://www.youtube.com/watch?v=J1QU\_R4MQQc
You can download the example code from my GitHub Project.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
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.
Some body asked me that Why do we have to implement singleton pattern when we have static. And here in your post you say that either we can use static method or implement it as Singleton. Can you please detail on this?
- Siva
Thanks for the clear explanation. I have one doubt here in Factory pattern. We have two concrete classes implementing the interface/Abstract class whose instances are created inside Factory class.But, instead of below line Computer pc = ComputerFactory.getComputer(“pc”,“2 GB”,“500 GB”,“2.4 GHz”); we can also use Computer pc=new PC(“pc”,“2 GB”,“500 GB”,“2.4 GHz”); to get new instance of PC. Then what is the advantage of using ComputerFactory.getComputer() method on the client side directly.?
- vamshi
Now i found the perfect article for Design pattern. Thanks Pankaj
- panky031
Nice article !!!
- Gani Victory
It seems to me that you’re showing what is called a simple factory with ComputerFactory; It is not the Factory Method Pattern. The client TestFactory delegates the creation to another class which it is composed with. If you want to implement the Factory Method Pattern,: 1. ComputerFactory should define an asbtract method getComputer(String ram, String hdd, String cpu) 2. ComputerFactory should have two subclasses PCFactory and ServerFactory.which implements the superclass abstract method to return either a PC or a server 3. The client should be given one of the two concrete factories and call the factory method to get PC or servers, depending which one was instanciated
- JocelynL
I am relatively new to design patterns but I need to ask this question. What if we need to add another subclass of computer say Laptop to the application.? Does this mean we will have to modify the computer factory class? This looks like violating the OO principle which says classes should be closed to modification but open to extension.
- Stephen Ubogu
Yes. Its very nice article about simple factory covers basic concepts.
- Vishal
Hi, is there a place in which I can download all the source code for the several design pattern examples. These are great examples, but I have to copy-paste each single text box into Intellij, and it is very cumbersome. Thank you very much, and congratulations for such good material.
- Luis Cunha
It’s a very good tutorial. But I have a doubt, You mentioned Calendar#getInstance() as factory pattern implementation. But in this there is a small difference right? There is no separate factory class. The super class Calendar itself is acting as the factory class. Does an implementation like this have any advantage or disadvantage?
- Prashanth
Where below are implemented import com.journaldev.design.abstractfactory.PCFactory; import com.journaldev.design.abstractfactory.ServerFactory;
- BkOfc