Factory Design Pattern or Factory Method Design Pattern. It is a widely used and easy to understand design pattern. It is an effortless but effective way to hide the complexity of object creation. That’s why it belongs to the creation pattern category.

Prerequisites for understanding the Factory Design Pattern

Before you can understand what the Factory Design Pattern is, you need to know what superclasses superclasses and subclasses subclasses are. If you already know, you can skip to this section

Superclasses and subclasses/parent classes and subclasses

A superclass is a class or interface defined as a base class. Subclasses are classes that extend or implement it (superclasses). For example, Student is an interface (or you can set it as a class, it’s up to you). Now there can be multiple types of students. No, I’m not talking about A+ or F students, I don’t want to make fun of myself here.

Instead, let’s assume it’s based on a different course. Finance students, computer students, or art students, for example. These are different classes, but they’re all type students, right? Therefore, we will implement the student interface for each student type. Once any class is implemented or extended, the current class becomes a subclass of it. In our case, all these students, FinanceStudent, ComputerStudent and ArtStudent are subclasses of Student. Student is a superclass or base class of these subclasses (yes, even if it is an interface).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
interface Student {
  String getName();
}

class FinanceStudent implements Student {
  public String getName(){
    // do something
  }
}
// same for ComputerStudent and ArtStudent

Challenges

In the above small example, we have many studentclasses and more studentclasses. normally, we will create each student separately as shown below.

1
2
3
4
Student st = new FinanceStudent("Student 1");
Student st2 = new ArtStudent("Student 2");
...
Student stN = new NthCoursedStudent("Student Nth");

In the above example, each time you need any student, you need to explicitly select the appropriate student type and call the new keyword. Now the problem is that for art students, we want to pass some default value each time we create an object. Or, we would like to validate the supplied string to the student class. This would be difficult to handle because object creation is scattered throughout the code. It would be even more cumbersome because for each student type, you would need to add validation logic. So how do we solve this challenge?

You must be thinking, what if we could collect all this student creation logic into one class or function? Interestingly enough, what you are thinking about is basically the factory design pattern. Let’s dive into it.

What is the Factory Design Pattern

Simply put, it’s a way to put object creation logic (similar to a type) into a single class or function. Similar to a factory. You simply ask the factory to produce a certain product. The factory is responsible for building the product according to your requirements and providing you with the final product. You don’t have to worry about what happens in the factory.

In the previous example, we created the student class for the nth time. Let’s apply the factory design pattern (in a very simple way) to it.

Creating a factory design class

Remember, I am creating a very simple model that you can customize to your needs.

Let’s start with the factory base class. And create a function called createStudent in it. And make it public and static for easy access. We will worry about how to create it later. Your current code might look like this.

1
2
3
4
5
6
class StudentFactory {
    public static Student createStudent(){
        // TODO
       return null;
    } 
}

Now, how do we determine which type of student needs to be created? To do this, we can use strings or we can use enums to get more maintainable code.

1
2
3
enum StudentTypes {
    FINANCE, ART, COMPUTER;
}

The next step is to get this enum as a parameter in the createStudent method along with the student name. After that, we will simply execute the if-else or switch condition.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
public static Student createStudent(StudentTypes studentType,
                                    String name) {
    System.out.printf("Creating %s student object with name %s \n"
            , studentType, name);
    
    switch (studentType) {
        case FINANCE:
            return new FinanceStudent(name);
        case ART:
            return new ArtStudent(name);
        case COMPUTER:
            return new ComputerStudent(name);
        default:
            // returning null is not recommended
            return new ComputerStudent(name);
    }
}

That’s it, that’s your factory design pattern. Now you can just call the createStudent function with the appropriate types enum and voila to get the student object. Now you must be wondering what’s in it for you, right? Let’s look at one of the scenarios I mentioned in the challenge section.

Benefits of the Factory Design Pattern

Suppose we want to validate the name provided. Check if it is empty. If it is empty, throw an exception. Before FDP, we had to check the name independently before each creation logic. This would be a redundant task. But now, using the FDP functions we created, we only have to write and call the logic once. We can write the null check before the switch statement. Or, if you have long validation logic, it is simple to just create a separate function and call it before the switch statement.

1
2
3
if(name == null){
    throw new RuntimeException("name is null");
}