Factory Design Patterns in Java
Factory Design Patterns in Java. One of the goals of software development is to design products in such a way that the software can incorporate changes easily. The de facto standard in today's date is to follow the classic design patterns. Whatever modifications are needed can be done in a shorter span of time than it really takes. If a software development team writes code that needs a lot of modifications to add simple extensions to the product, they are not following the best practices. Design Patterns help solve a lot of ambiguities by providing an approach to write extensible code that does not need many changes while incorporating some new additions to it. The experts in the software industry follow standard design patterns or come up with their own to make their overall process efficiency. In this article, we are going to see one of those classic design patterns called the factory design pattern.
Factory Design Patterns in Java
Factory Design Patterns in Java. We have used simple factory design pattern examples in java for demonstrational purposes.
What kind of problem does the factory design pattern solve? Why use the factory design pattern in Java?
We know what you are thinking - Why use factory design pattern in Java? For a start, classes in java or any other object-oriented programming language are generally written in a way that leads to coupling problems, unless design patterns are used. Subclasses get highly dependent on each other when the code gets larger and larger and that is where the real problem begins. If that class needs some extra methods or maybe a new feature class is to be added, figuring out the modifications to be made to that class will take a lot of time because chances are high that making a simple change to a class may have rippling effects, as they might need changes as well (even the main class may not look the same again after making changes). This cannot go on forever and we need some elegant way to avoid such a situation.
Long story short – Why use a factory design pattern?
Answer: Following the factory design pattern can help solve the dependency issues.
Take a look at the code below, the DrinkCafe class has a createDrink method that does all sorts of stuff from choosing a drink to creating one and then finally returning it.
Fig: Factory Design Pattern Example in Java – drinkCafe Class
The problem with this type of code is that one class – drinkCafe, depends on all the subclasses that are being created inside of it. Any changes that may occur inside any subclass will eventually force us to make changes to the drinkCafe class as well. It should be pretty clear that reducing dependencies to concrete classes in our code should be considered a “good thing”.
What is the factory method? Factory Design Pattern Definition.
As the name suggests, factory design pattern deals with “factories”. What exactly does a factory do? Well, they create stuff! A factory is a method that deals with details of creating objects. Therefore, this design pattern falls in the Creational category of design patterns. There are other patterns also that fall in this category, such as the Singleton Design Factory. The factory design pattern says that code should be open for extension but closed for modification, as all patterns agree to that.
Let's begin by looking at a code example, below is a method that instantiates a class:
Fig: Factory Design Pattern Example in Java - orderDrinkMethod
Once you have written this code for ordering a drink, you realize that it needs to determine the type of drink as well. So, you make the following changes.
Fig: Factory Design Pattern Example in Java – orderDrinkMethod extended
Now the code looks a little more verbose and this is generally how we write a method. However, if we want to add some other types of drinks or remove some other types will make it really messy to incorporate frequent changes.
Let's follow a basic approach to factory design patterns and see if that is of any help. Let's separate out the orderDrink method and the code that determines the type of drink (the one that creates objects of concrete classes, ColdDrink and HotDrink) and put it inside the DrinkFactory class.
Fig: Factory Design Pattern Example in Java – DrinkFactory and DrinkCafe classes
Notice what we did there, we moved out the createDrink logic, which was involved in instantiating new objects to a separate class. The method that implements the logic of creating objects of concrete classes has a special name, factory method. In the factory design pattern, the factory method should be the only one method that refers to concrete classes (by concrete we mean classes that are of their own type having specialized behavior to themselves, HotDrink and ColdDrink in our case and that do not need frequent changes to code). If we want to bring in a new drink, the only place that needs to change is the Drink Factory class. Thus, restricting us to make changes to only one class and easily extend the code to incorporate a new drink. We just need to create a new drink class that implements the Drink abstract class.
Factory Method Pattern
Let's expand our code example to understand what the Factory method pattern is. All factory design patterns encapsulate the creation of objects. The Factory Method Pattern extends this idea and encapsulates object creation by letting subclasses decide what objects to create.
First of all, notice that we have taken the createDrink method from the DrinkFactory class and have put that into the DrinkCafe class and also declared createDrink as an abstract method.
Fig: Factory Design Pattern Example in Java – drinkCafe abstract class
Now, let's create subclasses for this class, they will decide what objects to create instead of the drinkCafe class.
Fig: Factory Design Pattern Example in Java – subclasses of drinkCafe
By the way, Drink class has the following code structure.
Fig: Factory Design Pattern Example in Java – Drink Class implementation
Hot Drink and Cold Drink classes have the following code structure:
Fig: Factory Design Pattern Example in Java – Types of Drink Classes
How do these all co-relate? See the snippet below:
Fig: Factory Design Pattern Example in Java – instantiating the subclasses
We can think of the factory method pattern in terms of creator and product classes. In our case, drink cafe is an abstract creator class that defines an abstract factory that is implemented by the subclasses to produce drinks. In terms of class hierarchies, we have the drinking class that acts as the interface for hot and cold drink subclasses whereas the drinkCafe class is the interface for village and city style cafes. By creating abstract methods and classes we can see in the java example above that, subclasses are the ones that decide which class to instantiate depending on the need, this way only the classes that need to be modified will be the Drink and drink cafe classes if we want to extend our examples to other types of classes or drinks. The end goal is always to decouple the class dependencies.
Factory Method Pattern definition
Now you have got the better of the factory design pattern example in java, you can now understand the factory method pattern definition. As with every factory, the Factory Method Pattern gives us a way to encapsulate the instantiations of concrete types. The Factory Method Pattern defines an interface for creating an object, but lets subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
What is the abstract factory design and how is it different from the factory method design pattern?
You can think of abstract factory design as a means of adding more flexibility to code extensibility. As you can see the snippets of factory design patterns in java used in earlier examples, we have used abstract classes and methods. The core focus was to encapsulate the instantiations of concrete types. The goal of abstract factory design is the same but has a slight difference. An Abstract Factory gives us an interface for creating a variety of products. By writing code that uses this interface, we decouple our code from the actual factory that creates the products. A variety of products can be all the different types of drinks, and decorative items or ingredients for the Drink class. The client code will remain same if we follow the abstract factory design pattern because, all we will have to do is implement the factory as we like in subclasses and passing in a variety of factories, we get a variety of implementations keeping the main code same.
Advantages of factory design pattern
The most significant advantage among all other advantages of the factory design pattern is that it helps in decoupling the creator class from its subclasses. If we add additional features or change a feature’s implementation, it will not affect your Creator Class (because the Creator is not tightly coupled to any Concrete Class). The other advantages of the factory design pattern are :
It allows subclasses to choose the types of object to create, this is what it means when we say subclasses “decide” which class to instantiate as the parent class has no idea of what object is being created, thus loose coupling.
It gives rise to the abstraction principle, the more abstract out implementation is, the fewer dependencies we have in our code.