Java Design Patterns: Creational Patterns Overview

Pragati Singh 🇮🇳🇸🇦
mobidroid
Published in
12 min readJan 4, 2019

Creational design patterns are a way of structuring code to make it more simple, maintainable, and effective. I’ll share the specific details of the most well-known creational patterns. I’ll also discuss when to use them to improve your code. So join me in my course to learn how to write cleaner, simpler, and more maintainable code.

What is a design pattern? A design pattern is a way of structuring code to solve a specific problem. The aim is always to make use of solutions to common problems and make code more elegant and flexible. Design patterns do not require knowledge of any complex or obscure code to be able to use them. But knowing how to use the right design pattern in the right situation will make you a much better programmer. Often, using a design pattern will make the code simpler, shorter, and more elegant, by allowing it to be reused in other places.

The book is called Design Patterns: Elements of Reusable Object-Oriented Software. The authors of the book are four computer scientists called Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides. They are often referred to as the Gang of Four, and the book is often credited with being a milestone in how software is written. One of the key advantages of using design patterns is that they are a way of reusing other people’s knowledge. Instead of starting from scratch to try and find the best way to solve a problem, a good solution can be used and repeated to solve the same problem again and again.

Learning design patterns are an important part of learning to write Java programs and are also very useful in refactoring existing code. The ability to make use of existing design patterns to solve common problems will make you a faster and better Java programmer.

Creational design patterns are used to abstract the process of instantiating objects. They are used in scenarios when a system should not be dependent on how objects are created. One example could be a game that lets you build houses. It would not be practical to have one long class that has all the code for making each different type of room and all the items in the room. It would be much better to encapsulate the code for creating the objects in separate ways. There are lots of creational design patterns that could be applied to this game. Creational design patterns become more important as systems become more complex.

There are two main themes that are common to most creational design patterns.

  1. They encapsulate knowledge about which concrete class the system should use.
  2. They conceal how objects are created and put together.

Following are the most creational common design patterns.

  1. Builder pattern
  2. Prototype pattern
  3. Factory Method pattern
  4. Abstract Factory pattern
  5. Singleton pattern
  • A design pattern allows you to reuse other people’s knowledge .
  • Creational design patterns abstract the process of instantiating objects.

Builder pattern is to avoid having complex constructors. In general, you should avoid having a constructor that takes a large number of parameters. Long lists of parameters are confusing and do not give you much flexibility when creating a class. Consider the case of a class representing a person. Each new person created will have a unique combination of characteristics. For example, each person will have a name, age, hair color, eye color, occupation, nationality, and so on and so forth. In a Java application, every time a person was created, all of this information would have to be passed into the constructor.

Builder pattern Fig 1

This is a very long list that needs to be supplied, and it is easy to see how items might be put in the wrong order. There might also be times in the application where not all of the information is needed. You might need to create a person but only want to specify their name. To create a person you would still have to supply all of the other information about their hair color, nationality, current city, etc. One way to fix this problem is to have multiple constructors. They could be one that takes all the parameters and another that takes just the name.

Then if one was needed there could be another constructor that takes just the first two parameters, name and age. Then there could be one that takes the first three and then the first four and so on until all the parameters are added. This technique is called the telescoping constructor pattern. The problem with this technique is the class ends up having a very large number of constructors. There may be times when you want to specify other combinations, for example, just nationality and date of birth. To have a constructor for every possible combination of eight parameters there would be 254 different constructors.

Builder pattern Fig 2

This solution does work and there would be a great amount of flexibility in creating person objects. But the person class would be extremely long and complex just from the number of constructors. It would take a long time to write all those codes and it would be difficult for other people to read and understand. The builder pattern is a much better alternative to solving this problem. It keeps all the flexibility of the telescoping approach but without the complexity. It moves the construction of complex objects out of the constructor. It also allows for different combinations of fields with one single construction process.

Classes that use the builder pattern scale much better and are far easier to read in this scenario.

Prototype pattern essentially involves making a copy of one original object. It is useful when you want to create a new object, but a similar one already exists.In particular, it should be used when you do not want a system to know details of how objects are created. Say for example, there is an application that simulates a field of rabbits, and the while the application is running, the rabbits breed. Instead of creating a new rabbit object each time, it would be easier and more efficient to clone a single prototype rabbit. This technique is particular useful if creating a new rabbit object is a memory-intensive process.

Prototype pattern

It can make the application faster, as well as make the code shorter and cleaner. If the prototype pattern is used and an original rabbit is copied. The copied rabbits can then be modified . For example, you could clone the original rabbit 10 times, and then give all of the rabbits their own name. This pattern should be used when the application using the cloned objects should not need to know about how an object is created. It is also useful when classes are loaded dynamically.For example, in an application that creates new rabbit objects as it runs, the rabbits are only created once the program has started running.

This can slow the program down because new objects are being created all the time. But if the objects can be cloned, this will save memory. Having a prototype in this example is particularly useful because all of the rabbits have very similar characteristics. If the aim of the application was to create a different range of rabbits with different names, ages, breed-typed colors and weights, then the prototype pattern would be less useful. In that case, we could still clone a rabbit, but we would then have to execute a lot of codes to change all of its characteristics each time.

There would little benefit of cloning over just creating a new rabbit object every time. In the classic prototype pattern,there is an abstract prototype class that has a method called clone. There are then concrete implementations of the prototype, which overrides the clone method. A client can then create a prototype object and obtain copies of it.

Factory Method pattern deals with the problem of needing to crate objects but not knowing exactly what type of objects need to be created. There might be a class that creates new objects, but when the class is written, you want to be flexible about the type of objects it creates. In fact, the class might have no idea what kind of objects it will want to create. For example, say that there is a candy store that sells different types of candy. The owners of the candy store will want to buy in stock, but when they open the store, they won’t know which candy they will want to buy in the future.The job of the store is just to sell candy.

Factory Method pattern

It is not the job of the store to get involved with exactly how the candy is created. The solution to this problem is to usethe factory method pattern. This involves adding an extra class between the candy store and the candy. This class has something called a factory method which handles deciding which class to return. This means that all the code that decides which candy to make is moved out of the candy store and into the candy factory. This makes it much easier if the owner of the shop wants to start selling new types of candy.

In that case, the code in the candy store class does not need to be changed at all anymore. Instead, the candy factory class worries about all of this for us. This makes the code much more maintainable. If the factory pattern was not used,the code would be much more difficult to maintain. There could be a class called candy store and then an abstract class called candy. Then, each different type of candy could be a concrete implementation of the abstract candy class. The store needs a way to get the candy.

The problem is the candy store class needs to create candy objects, as it cannot create them because candy is an abstract class. You cannot instantiate an abstract class in Java. But the store just needs to know that it sells different types of candy. It doesn’t need to know about all of the different kinds of candy available in the world. In this scenario, the only way to create a candy object in the candy store class is to specify what type of candy it is. One solution is to have a method with lots of if statements. For example, if the candy is in the chocolate section, create a chocolate bar;if it’s in the lollipop section, create a lollipop.

The candy store probably sells lots of different types of candy, so it is easy to see that this method is going to get long and complicated very quickly. If the store wants to sell a new kind of candy, the code in the candy store itself needs to change. Any changes to the way the candy is created or packaged need to be reflected in the code inside the candy store, too. Using the factory pattern method avoids these problems.

Abstract Factory Pattern provides an interface for creating families of objects without specifying what their concrete types are. It should be used when there is a system that creates objects, but how those objects are created should be hidden from view. In particular, it is used when applications have families of objects. The application should be able to choose which of a selection of families it wants to use. The abstract factory pattern can ensure that family groups are used together. Say, for example, there is an application that builds bicycles.

First, all of the individual bike parts need to be built. The wheels, handlebars, gear and frame, and so on, need to be made, and not just any old parts. To make a mountain bike, for example, you need wheels with a strong frame and thick tires. Mountain bikes also need straight handlebars, so these different parts are examples of a family of objects that need to be made together. The process of making a mountain bikeis different to making a road bike, which has different wheels, gears, handlebars and so on. It would be wrong to mix up any of the parts for the two bikes.

If the road bike had a mountain bike wheel, it would not work very well. Both types of bikes have the same kinds of parts,i.e., they both have wheels, but the actual parts themselves are different. This can be complex when it comes to representing a bike builder in Java code. A constraint of a bike builder class is that it does not want to hard code the parts when a specific bike is built. This would be inflexible and lead to long and complex code all in one place. If any changes needed to be made to how a specific type of bike part is built, this code would need to change again.

The BikeBuilder shouldn’t need to care about how the bike parts are built. It just wants to ask for the bike parts and be given them. The abstract factory pattern solves this problemby providing an interface for making different types of bikes.In this case, there would be an interface called BikeFactorywhich has two concrete implementations,MountainBikeFactory and RoadBikeFactory, and MountainBikeFactory would return a mountain bike wheel,which is a concrete implementation of a wheel interface, and a RoadBikeFactory would return a road bike wheel, which is another concrete implementation of Wheel.

This way, the bike builder does not need to know about how the different parts are made because the concrete classes are isolated from it. It also promotes consistency. If the bike builder is using a MountainBikeFactory class, it cannot create any parts other than a mountain bike part. If it asks for a wheel, a mountain bike wheel is created and returned. There is no need to specify that a mountain bike wheel is needed,because the abstract factory already knows and deals with that. This is a much better way to structure the code.

Singleton pattern should be used when you want to make sure that only one instance of a class can be created. There might be times when you want to make it impossible to create multiple instances of a class while still making sure that there is a way to access that one instance.So in what situation would you need to do this? Some typical examples include window managers, database connectors, file managers, user interface dialogs, and resource accessors and spoolers. Say, for example, that you have a class that controls access to a resource like a printer.

Singleton pattern

You might have multiple printers, but you would want to make absolutely sure that only one instance of the class that controls access to them could be created. If there are multiple print spoolers, they might try and allow two different processes access to the printer at the same time. Or say you had a logging class that needs to be used repeatedly by all the files in your project. Again, you would want to make sure that there was only one instance of that logging class. Having multiple instances might cause your program to give incorrect results, behave strangely, or crash.

The solution to this problem is to use the Singleton pattern so that only one instance of the print spooler, or the logging class, could be created. There are some examples of the Singleton pattern in the Java API. For example, the Desktop class, the System class, and the Runtime class. Every Java application has one, and only one, instance of Runtime, which can be accessed with the public method get Runtime. The Singleton pattern is perceived as one of the simpler creational design patterns and it is fairly straightforward to understand the concept, but it shouldn’t be overused.

If you find that you have lots of examples of the Singleton pattern in your code, it might be a better option to refactor.However, it is a well-known pattern and an important concept to understand, and there are many situations when it comes in useful.

Thanks for reading. I wish you have a happy reading.

Note:- I have took an Effort to summarize design pattern here .

--

--

Pragati Singh 🇮🇳🇸🇦
mobidroid
Editor for

CISM | PMP | CISA | CHFI | GenAI | Program Director | Digital Transformation & Cybersecurity Leader | Chief Transformation Officer | ITO Head