It is a humid, cloudy and rainy day the Twin Cities of Minneapolis and St. Paul. Probably the only redeeming feature is that the Final Four is being played at the US Bank Stadium in Minneapolis. There are several streets closed in Minneapolis. Yesterday in the evening news you could see the amount of people eating, buying memorabilia, watching concerts, even riding a Ferris wheel built at a street intersection. It seemed that people were having lots of fun.
Yesterday morning I woke up shortly before 04:00 AM. I wanted to check on some tests running on a couple computers at home and had to write some documentation. I just got up and finished the tasks in the first 2-hour block of the day. Woke up my wife and had breakfast. She had plans with a friend to go shopping early morning. They were back around noon. We ended up having hotdogs for lunch, but what is most important, they had fun.
I received a message from HackerRank to solve the Java Singleton Pattern challenge. Note that the pattern may be used in any object oriented programming language. As I have mentioned in multiple occasions, I reference two books when I need to lookup design pattern; these are: Design Patterns and Agile Software Development.
To design a singleton class:
o Make constructor as private.
o Write a static method that has return type object of the singleton class.
The concept of Lazy initialization in used to write the static method that returns the instance of the class.
The difference in normal and singleton class in terms of instantiation is that, for normal class we use constructor, whereas for singleton class we use a method generally named getInstance(). In the challenge, HackerRank requires the name of the method to be getSingleInstance(). This was probably motivated to get through that the returned value is (in most cases) a single instance of the class.
In general, to avoid confusion, we may also use the class name as method name while defining this method.
In my solution I have implemented both approaches. Of course, I could only submit one in order to match the requirements of the challenge.
In this challenge, there is no input. HackerRank does all the output. You can read the requirements at their site.
I did write a Solution to test the implementations. The output from the console of the Eclipse IDE follows:
main <<< w.str ==>class instantiated<== main <<< x.str ==>CLASS INSTANTIATED<== main <<< w.str ==>CLASS INSTANTIATED<== main <<< y.str ==>class instantiated<== main <<< z.str ==>CLASS INSTANTIATED<== main <<< y.str ==>CLASS INSTANTIATED<==
The code for my Solution follows:
/* * Scaffold to test singleton pattern. */ public static void main(String[] args) { // // **** attempt to instantiate the constructor (compiler prevents it) **** // Singleton singleton = new Singleton(); // **** instantiate the singleton **** Singleton w = Singleton.getSingleInstance(); System.out.println("main <<< w.str ==>" + w.str + "<=="); // ***** instantiate the singleton **** Singleton x = Singleton.getSingleInstance(); // **** alter the string **** x.str = x.str.toUpperCase(); System.out.println("main <<< x.str ==>" + x.str + "<=="); // **** w and x refer to the same instance **** System.out.println("main <<< w.str ==>" + w.str + "<=="); System.out.println(); // // **** attempt to instantiate the constructor (compiler prevents it) **** // MySingleton mySingleton = new MySingleton(); // **** instantiate the my singleton **** MySingleton y = MySingleton.MySingleton(); System.out.println("main <<< y.str ==>" + y.str + "<=="); // **** instantiate my singleton **** MySingleton z = MySingleton.MySingleton(); // **** alter the string **** z.str = z.str.toUpperCase(); System.out.println("main <<< z.str ==>" + z.str + "<=="); // **** y and z refer to the same instance **** System.out.println("main <<< y.str ==>" + y.str + "<=="); }
As you can see, I tried to instantiate the constructor of the Singleton class. That produces a compiler error. I commented out and left it so you can verify this.
We then get an instance of the Singleton class and we display the value of a public string. The string is set by the constructor. We then instantiate (get) a second instance of the class. By changing the string in the first instance we expect it also changed in the second instance. We verify this is the case.
The process repeats with a second class named MySingleton. The instantiation is different but the results are the same. We only get one instance.
The code for the Singleton class follows:
package singleton.pattern.canessa; /* * Using getSingleInstance() to get access to the instance. */ public class Singleton { // **** variable **** private static Singleton singleInstance = null; public String str; // **** constructor **** private Singleton() { str = "class instantiated"; } // **** creates an instance of this class **** public static Singleton getSingleInstance() { // **** create the single instance (if needed) **** if (singleInstance == null) singleInstance = new Singleton(); // **** return the single instance **** return singleInstance; } }
The code for the MySingleton class follows:
package singleton.pattern.canessa; /* * MySingleton.MySingleton to get access to the instance. */ public class MySingleton { // **** variable **** private static MySingleton singleInstance = null; public String str; // **** constructor **** private MySingleton() { str = "class instantiated"; } // **** creates an instance of this class **** public static MySingleton MySingleton() { // **** create the single instance (if needed) **** if (singleInstance == null) singleInstance = new MySingleton(); // **** return the single instance **** return singleInstance; } }
I will try to get an additional post over the weekend to try the Singleton pattern in a different scenario.
Hope you enjoyed this post. If you are interested you can find the entire solution in my GitHub repository.
As usual, if you have comments on this post or any other post in this blog, or if you would like me to help in and phase of the SDLC for a project, please feel free and leave me a note below. Notes requesting help will be kept private.
Keep on learning and experimenting. It is the best way to learn!
John
Follow me on Twitter: @john_canessa