Factory Pattern

The factory pattern simply generates an instance for client without exposing its instantiation logic to the client.

class_diagram_of_factory_pattern_in_java1-8964987

In object-oriented programming (OOP), a factory is an object used to create other objects. In other words, a factory is a function or method that returns objects of a varying prototype or class from some method call, which is assumed to be “new“.

Factory pattern simply generates an instance for client without exposing its instantiation logic to the client.

As the name suggests, a factory is a place where different products are created, similar in features yet divided into categories. In Java, a factory pattern is used to create instances of different classes of the same type.

We use the factory pattern because if the object creation logic is spread throughout the whole application, and if we need to change the object creation process, you must go to every place to make the necessary changes. Factory patterns help put the object creation logic in a central place so changes can be made easily.

1. When to use Factory Pattern?

The factory pattern introduces loose coupling between classes, which is the most important principle to consider and apply while designing application architecture. Loose coupling can be introduced in application architecture by programming against abstract entities rather than concrete implementations. This not only makes our architecture more flexible but also less fragile.

A picture is worth a thousand words. Let’s see what a factory implementation will look like.

class_diagram_of_factory_pattern_in_java1-8964987

The above class diagram depicts a typical scenario using an example of a car factory that can build three types of cars: small, sedan, and luxury. Building a car requires many steps, from allocating accessories to final makeup. These steps can be written in programming as methods and should be called while creating a specific car-type instance.

2. Factory Pattern Implementation

So far, we have designed the classes that need to be designed for making a CarFactory. Let’s code them now.

2.1. Car Types

The CarType enum will hold the types of cars and will provide car types to all other classes.

public enum CarType {

    SMALL, SEDAN, LUXURY
}

2.2. Car Implementations

The Car is the parent class of all car instances, and it will also contain the common logic applicable to car making of all types.

public abstract class Car {
 
  public Car(CarType model) {
    this.model = model;
    arrangeParts();
  }
 
  private void arrangeParts() {
    // Do one time processing here
  }
 
  // Do subclass level processing in this method
  protected abstract void construct();
 
  private CarType model = null;
 
  public CarType getModel() {
    return model;
  }
 
  public void setModel(CarType model) {
    this.model = model;
  }
}

LuxuryCar is the concrete implementation of car type LUXURY.

public class LuxuryCar extends Car {
 
  LuxuryCar() {
    super(CarType.LUXURY);
    construct();
  }
 
  @Override
  protected void construct() {
    System.out.println("Building luxury car");
    // add accessories
  }
}

SmallCar is the concrete implementation of car type SMALL.

public class SmallCar extends Car {
 
  SmallCar() {
    super(CarType.SMALL);
    construct();
  }
 
  @Override
  protected void construct() {
    System.out.println("Building small car");
    // add accessories
  }
}

SedanCar is the concrete implementation of car type SEDAN.

public class SedanCar extends Car {
 
  SedanCar() {
    super(CarType.SEDAN);
    construct();
  }
 
  @Override
  protected void construct() {
    System.out.println("Building sedan car");
    // add accessories
  }
}

2.3. Factory to Create Objects

CarFactory.java is our main class implemented using factory pattern. It instantiates a car instance only after determining its type.

public class CarFactory {

  public static Car buildCar(CarType model) {

    Car car = null;

    switch (model) {
    case SMALL:
      car = new SmallCar();
      break;
 
    case SEDAN:
      car = new SedanCar();
      break;
 
    case LUXURY:
      car = new LuxuryCar();
      break;
 
    default:
      // throw some exception
      break;
    }
    return car;
  }
}

3. Demo

In TestFactoryPattern, we will test our factory code. Let us run this class.

public class TestFactoryPattern {

  public static void main(String[] args) {

    System.out.println(CarFactory.buildCar(CarType.SMALL));
    System.out.println(CarFactory.buildCar(CarType.SEDAN));
    System.out.println(CarFactory.buildCar(CarType.LUXURY));
  }
}

Program Output.

Building small car
designPatterns.creational.factory.SmallCar@7c230be4
Building sedan car
designPatterns.creational.factory.SedanCar@60e1e567
Building luxury car
designPatterns.creational.factory.LuxuryCar@e9bfee2

As you can see, the factory can return any type of car instance it is requested for. It will help us in making any kind of changes in the making process without even touching the composing classes i.e. classes using CarFactory.

4. Benefits of Factory Pattern

By now, you should be able to count the main advantages of using the factory pattern. Let’s note down:

  • The creation of an object precludes its reuse without significant duplication of code.
  • The creation of an object requires access to information or resources that should not be contained within the composing class.
  • The lifetime management of the generated objects must be centralized to ensure consistent behavior within the application.

5. Summary

Factory pattern is most suitable where some complex object creation steps are involved. A factory pattern should be used to ensure these steps are centralized and not exposed to composing classes. We can see many real-life examples of factory patterns in JDK itself, e.g.

I hope I have included enough information in this Java factory pattern example to make this post informative.

If you still have questions about the abstract factory design pattern in Java, please leave a comment. I’ll be happy to discuss it with you.

Happy Learning !!

Leave a Comment

  1. in factory pattern.
    If we have 1 laks sub classes ,then how to create factory.

    if else condition,we cant put in factory class for 1 laks subclassess.
    Please explain.

    Reply
    • We can use Reflection but it is costly and usecase specified by you doesn’t make sense either.
      Anyway below is the partial code snipet.

      1. Modify CarType enum to include classname as well.
      Like for SMALL –> SmallCar etc.

       
      public enum CarType{
          SMALL("SmallCar");
          private String className;
          public String getClassName(){return className;}
          public void setClassName(String className){this.className = className;}
          private CarType(String className){this.className = className;}
      }
      2. You can iterate over CarType enum.
      
      public static Car buildCar(CarType model) {
              Car car = null;
             for(CarType carType : CarType.values) {
                 if(model.equals(carType)) {
                     car = Class.forName(carType.getClassName()).getConstructor().newInstance();
                     break;
                 }
             }
          if(null == car){
               // throw some exception
         } 
        return car;
      }
      
      Reply
  2. What if we need to add another car type as SUV then we need to change CarFactory which is not good practice as it voilates Open close principle.am i correct?

    Reply
    • Adding a new CarType should not violate Open Close principle as we are not modifying any functionality of factory class by adding logic to create instance for SUV.
      It works as it was working earlier.

      Reply
      • Hi Shivan, Yes you are correct, but CarFactory class changes if we add new car type, So CarFactory class violate OCP,
        Instead of if else or for loop, We can create separate factory for each car type and let client decide to choose.
        Please share your though on this. Thanks

        Reply
    • “Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.”

      In case of you adding another if -else/ switch case, you are sort of extending the functionality of providing with another type of object but somewhat of the same type (thanks to abstract class/interface).But you are not modifying it.

      I build a factory today to produce different kinds of chips, package and sell them. I start with potato chips and then EXTEND to produce banana chips. I am extending my functionality, not modifying the behaviour, I AM STILL A CHIPS FACTORY.

      In case you have a library which today provides you with 3 Types of objects, – CAR, if you want to modify it and also provide with a ELECTRIC CAR, you have to recompile and provide the new upgraded jars. But you are still providing cars.

      If you completely change/modify the behaviour it will be a problem. I think this is what OCP means. PLease pitch in in case it is wrong. Thanks

      Reply
  3. Definitely, if it’s “modern” or “up-to-date” to instantiate classes in Java within a switch case statement, you need to change your programming language right now. Consider moving your skills to a professional programming language. You are working very hard in Java. A real software development don’t need to be very hard. Regards.

    Reply
    • Hi Fabian, Thanks for the suggestion but perhaps it will be unnecessary. I really looked up in outer world to find if I am THE alien, but found plenty of guys like this.

      I will not say that you are incorrect, but will appreciate if you can express your thoughts with facts/reasons. OR you can suggest your edit in wikipedia page because there I could see the same thing.

      Reply
  4. Hi Lokesh,
    How do you avoid casting after getting back an instance?

    LuxuryCar lc= (LuxyryCar) FactoryManager.buildCar(CarType.LUXURY);

    Reply
  5. I might sound silly , why the concrete classes (Sedan,etc) are public. Since we are exposing a factory class to create us instance , it doesn’t make sense to have them public right , any one can create new instance of these classes directly from anywhere, ain’t they ??

    Reply
  6. Hi in the original GOF factory pattern, there is a concept of having a creator and a concrete creator. I find this missing in your example. The CarFactory class is of course the concrete creator , but it does not extend from an abstract class / interface (creator)

    So is it OK to call it a factory pattern without having the creator / concrete creator

    Reply
  7. It’s impossible to read this article on Samsung Galaxy 10.1 – the black advert strip jumps to the center of the webpage and covers the article text.

    Reply
  8. How to reuse the same object? i.e If we call – CarFactory.buildCar(CarType.SMALL) multiple times, it returns a new object for every call.

    Regards,
    Praveen Das

    Reply
    • Hi Praveen, another question in response to your question. Why would a factory will return the same instance on each request? What’s use of this approach? I believe you will have a good reason for it, so please share with us. It will expand our thought process as well.

      To answer your question, you can apply singleton pattern on different Car objects and return from construct() method.

      On another thought, you should better using prototype pattern, if you want to save some CPU cycles in car construction process. Singleton simply doesn’t make sense to me.

      https://howtodoinjava.com/design-patterns/creational/prototype-design-pattern-in-java/

      Reply
      • Hi Lokesh, I’m looking at implementing a mailbox which fetches messages at a specific time interval.

        Each messages fall under different types of validations, so depending on the NotificationType i call the ValidationFactory.

        since there are for ex:22 notifications, and 100 messages, the notifications can be of same type. in this case i should be able to reuse the already created object for that particular NotificationType.

        NotificationType would be my enum class.

        ValidationService would be the parent class for all validation instances.

        ValidationFactory would get me the respective object for the notificationType as input.

        Regards,
        Praveen

        Reply
        • I don’t think that Factory is the pattern you are looking for. However if you really want to use Factory pattern as your approach you should combine it with a caching adapter for the actual Factory which returns the cached instances.

          Reply
  9. Thanks for this wonderful example. My doubt is why do I get a warning in my IDE that the method “construct()” shouldn’t be called in side the construtor because it’s an overridable method?

    I read that it has something to do with inheritance and if other classes extend this class things COULD go wrong down the line if someone overrides that method in another place.

    Did I understand correctly the potencial danger here?

    Reply
    • There is a danger in doing this and you should not do it (add overridable methods in the constructor)

      Effective Java 2nd Edition, Item 17: Design and document for inheritance or else prohibit it

      “There are a few more restrictions that a class must obey to allow inheritance. Constructors must not invoke overridable methods, directly or indirectly. If you violate this rule, program failure will result. The superclass constructor runs before the subclass constructor, so the overriding method in the subclass will get invoked before the subclass constructor has run. If the overriding method depends on any initialization performed by the subclass constructor, the method will not behave as expected.”

      Reply
  10. I guess there is one small mistake (inaccuracy) in your example.
    You have to make method constcut() abstract and put it into constructor instead of method arrangeParts():
    public Car(CarType model) {
    this.model = model;
    //arrangeParts(); // remove this. You cold leave it but it just misslead you, it has nothing to design pattern.
    construct(); // abstrac method! will be called implementation from interited class.
    }
    Then constructor LuxuryCar will look like:
    LuxuryCar() {
    super(CarType.LUXURY);
    //construct(); // remove this!
    }

    Reply
  11. Good post, thank you. Could you make it a bit more complex (as part2) in the way, lets say: Car is composed of underframe, engine and body and each of this component is created by factory depending of type of a car. What I’d like to see is how those factories will be used together, where to put it, how to call it. Thanks

    Reply
  12. You did not mention where CarFactory.buildCar() should be called… You have just written the testing part but I suppose the integration part is missed…

    Reply

Leave a Comment

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.