JavaRush /Java Blog /Random EN /Patterns and Singleton - for everyone who encountered the...

Patterns and Singleton - for everyone who encountered them for the first time

Published in the Random EN group
This article is aimed at those who first encountered the concept of patterns, heard about Singleton'e, or somehow made it, but still did not understand anything. Welcome! JavaRush students encounter patterns for the first time at level 15, when unexpectedly the cap asks to “fix” and implement a pattern Singletonwith a lazy implementation. Students who hear about it for the first time Singletonimmediately have a bunch of questions: what is a pattern, why is it needed, what kind of pattern is it, Singletonand finally, what kind of lazy implementation is this. Let's start answering in order: Patterns and Singleton - for everyone who encountered them for the first time - 1

What is a pattern anyway?

For a better understanding, I think it’s worth answering this question from history. Among the programmers there is such a famous four authors: Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, who came up with an interesting idea.
Patterns and Singleton - for everyone who encountered them for the first time - 2
They noticed that when writing programs they often had to solve approximately the same problems and write code of the same type in structure. Therefore, they decided to describe in the form of patterns typical patterns that are often used in object-oriented programming. The book was published in 1995 under the title “Techniques of Object-Oriented Design. Design Patterns" . The title of the book turned out to be too long, and it simply became known as The Book of the Gang of Four . In the first edition, 23 patterns were published, after which dozens of others were discovered. So, answering the question in this paragraph, “What are patterns?” , let’s summarize in just a few words:
A pattern is a standardized solution to a common problem.
And Singletonthis is just one of these patterns.

Why do we need patterns (design patterns)

You can program without knowing patterns; you can verify this simply by realizing the fact that by the 15th level in JavaRush you had written hundreds of mini-programs without knowing anything about their existence. This suggests that a pattern is a kind of tool, the presence of which distinguishes a master from an amateur:
Patterns and Singleton - for everyone who encountered them for the first time - 3
The patterns describe how to correctly solve one of the typical problems. As a result, knowing the patterns saves you time. An analogy can be made with algorithms. For example, you can come up with your own sorting algorithm with blackjack and numbers and spend a lot of time on it, or you can use one that has already been described a long time ago and implement it. It's the same with patterns. Plus, with the use of patterns, the code becomes more standardized, and when using the right patterns, you will be less likely to make mistakes, since they were already foreseen and eliminated in this pattern. Well, plus everything, knowledge of patterns allows programmers to better understand each other. Simply saying the name of the template is enough, instead of trying to explain to your fellow programmers what you want them to do. So, to summarize, design patterns help:
  • do not reinvent the wheel, but use standard solutions;
  • standardize code;
  • standardize terminology;
In conclusion of this section, we note that the entire variety of patterns can be simplified into three large groups:
Patterns and Singleton - for everyone who encountered them for the first time - 4

Finally a Singleton pattern

Singletonrefers to generative patterns . Its literal translation is loner. This pattern ensures that a class has only one object (one instance of the class) and that a global access point is provided to that object. It should be clear from the description that this pattern should be used in two cases:
  1. when no more than one object of any class should be created in your program. For example, in a computer game you have a “Character” class, and this class should have only one object that describes the character himself.

  2. when you need to provide a global access point to a class object. In other words, you need to make sure that the object is called from anywhere in the program. And, alas, for this it is not enough to simply create a global variable, because it is not write-protected and anyone can change the value of this variable and the global access point to the object will be lost. These properties Singletonare needed, for example, when you have an object of a class that works with a database, and you need the database to be accessible from different parts of the program. And Singletonit will guarantee that no other code has replaced the previously created instance of the class.
These two problems are solved by Singleton: there must be only one object in the program and there must be global access to it. In the example at level 15, the cap asks to implement this pattern for the following task (here is its description):
Patterns and Singleton - for everyone who encountered them for the first time - 5
After carefully reading the condition, it becomes clear why exactly Singleton(Single) is needed here. After all, the program asks you to create one object of each class: Sun, Moon, Earth. And it is logical to assume that each class in the program should create no more than one Sun/Moon/Earth, otherwise it will be absurd, unless of course you are writing your own version of Star Wars. Feature of Java implementationSingleton in three steps Singleton behavior in Java cannot be implemented using a regular constructor because the constructor always returns a new object. Therefore, all implementations of Singleton'a come down to hiding the constructor and creating a public static method that will control the existence of a single object and “destroy” all newly appearing objects. If Singleton'a is called, it must either create a new object (if it is not already in the program) or return one that has already been created. To do this: #1. – You need to add a private static field to the class containing a single object:
public class LazyInitializedSingleton {
	private static LazyInitializedSingleton instance; //#1
}
#2. – Make the class constructor (default constructor) private (so that access to it is closed outside the class, then it will not be able to return new objects):
public class LazyInitializedSingleton {
	private static LazyInitializedSingleton instance;
private LazyInitializedSingleton(){} // #2
}
#3 . – Declare a static creation method that will be used to obtain the singleton:
public class LazyInitializedSingleton {
    private static LazyInitializedSingleton instance;
        private LazyInitializedSingleton(){}
        public static LazyInitializedSingleton getInstance(){ // #3
        if(instance == null){		//if the object has not been created yet
            instance = new LazyInitializedSingleton();	//create a new object
        }
        return instance;		// return the previously created object
    }
}
The above example is somewhat clumsy, because we simply hide the constructor and provide our own method instead of the standard constructor. Since this article is aimed at enabling JavaRush students to come into contact with this pattern (and patterns in general) for the first time, the implementation features of more complex Singletons will not be given here. We only note that depending on the complexity of the program, more detailed refinement of this pattern may be required. For example, in a multi-threaded environment (see the Threads topic), several different threads can simultaneously call the Singleton's getter method, and the code described above will stop working, because each individual thread will be able to create multiple instances of the class at once. Therefore, there are still several different approaches to creating correct Thread-safe singletons. But that's another story =) And finally. What is Lazy Initialization that the cap asked for ? Lazy Initialization is also called lazy initialization. This is a programming technique where a resource-intensive operation (and creating an object is a resource-intensive operation) is performed on demand, rather than in advance. Which is basically what happens in our code Singleton'a. In other words, our object is created at the moment it is accessed, and not in advance. It should not be assumed that the concept of lazy initialization is somehow strictly connected with Singleton'om. Lazy initialization is also used in other generative design patterns, for example in Proxy and Factory Method, but that's another story =) The following sources were used in preparing the article:
  1. Java Singleton Design Pattern Best Practices with Examples
  2. Design Patterns
  3. Correct Singleton in Java
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION