Update singleton

This commit is contained in:
Ilkka Seppälä 2021-06-22 20:10:26 +03:00
parent ebcc857664
commit 9a2c5aa9aa
No known key found for this signature in database
GPG Key ID: 31B7C8F5CC412ECB
2 changed files with 25 additions and 18 deletions

View File

@ -13,13 +13,12 @@ tags:
Ensure a class only has one instance, and provide a global point of access to it. Ensure a class only has one instance, and provide a global point of access to it.
## Explanation ## Explanation
Real world example Real-world example
> There can only be one ivory tower where the wizards study their magic. The same enchanted ivory > There can only be one ivory tower where the wizards study their magic. The same enchanted ivory
> tower is always used by the wizards. Ivory tower here is singleton. > tower is always used by the wizards. The ivory tower here is a singleton.
In plain words In plain words
@ -48,7 +47,15 @@ Then in order to use:
```java ```java
var enumIvoryTower1 = EnumIvoryTower.INSTANCE; var enumIvoryTower1 = EnumIvoryTower.INSTANCE;
var enumIvoryTower2 = EnumIvoryTower.INSTANCE; var enumIvoryTower2 = EnumIvoryTower.INSTANCE;
assertEquals(enumIvoryTower1, enumIvoryTower2); // true LOGGER.info("enumIvoryTower1={}", enumIvoryTower1);
LOGGER.info("enumIvoryTower2={}", enumIvoryTower2);
```
The console output
```
enumIvoryTower1=com.iluwatar.singleton.EnumIvoryTower@1221555852
enumIvoryTower2=com.iluwatar.singleton.EnumIvoryTower@1221555852
``` ```
## Class diagram ## Class diagram
@ -62,13 +69,13 @@ Use the Singleton pattern when
* There must be exactly one instance of a class, and it must be accessible to clients from a well-known access point * There must be exactly one instance of a class, and it must be accessible to clients from a well-known access point
* When the sole instance should be extensible by subclassing, and clients should be able to use an extended instance without modifying their code * When the sole instance should be extensible by subclassing, and clients should be able to use an extended instance without modifying their code
## Typical Use Case Some typical use cases for the Singleton
* The logging class * The logging class
* Managing a connection to a database * Managing a connection to a database
* File manager * File manager
## Real world examples ## Known uses
* [java.lang.Runtime#getRuntime()](http://docs.oracle.com/javase/8/docs/api/java/lang/Runtime.html#getRuntime%28%29) * [java.lang.Runtime#getRuntime()](http://docs.oracle.com/javase/8/docs/api/java/lang/Runtime.html#getRuntime%28%29)
* [java.awt.Desktop#getDesktop()](http://docs.oracle.com/javase/8/docs/api/java/awt/Desktop.html#getDesktop--) * [java.awt.Desktop#getDesktop()](http://docs.oracle.com/javase/8/docs/api/java/awt/Desktop.html#getDesktop--)
@ -77,8 +84,8 @@ Use the Singleton pattern when
## Consequences ## Consequences
* Violates Single Responsibility Principle (SRP) by controlling their own creation and lifecycle. * Violates Single Responsibility Principle (SRP) by controlling their creation and lifecycle.
* Encourages using a global shared instance which prevents an object and resources used by this object from being deallocated. * Encourages using a globally shared instance which prevents an object and resources used by this object from being deallocated.
* Creates tightly coupled code. The clients of the Singleton become difficult to test. * Creates tightly coupled code. The clients of the Singleton become difficult to test.
* Makes it almost impossible to subclass a Singleton. * Makes it almost impossible to subclass a Singleton.

View File

@ -30,20 +30,20 @@ import lombok.extern.slf4j.Slf4j;
* classloader instance and provides global access to it.</p> * classloader instance and provides global access to it.</p>
* *
* <p>One of the risks of this pattern is that bugs resulting from setting a singleton up in a * <p>One of the risks of this pattern is that bugs resulting from setting a singleton up in a
* distributed environment can be tricky to debug, since it will work fine if you debug with a * distributed environment can be tricky to debug since it will work fine if you debug with a
* single classloader. Additionally, these problems can crop up a while after the implementation of * single classloader. Additionally, these problems can crop up a while after the implementation of
* a singleton, since they may start out synchronous and only become async with time, so it may * a singleton, since they may start synchronous and only become async with time, so it may
* not be clear why you are seeing certain changes in behaviour.</p> * not be clear why you are seeing certain changes in behavior.</p>
* *
* <p>There are many ways to implement the Singleton. The first one is the eagerly initialized * <p>There are many ways to implement the Singleton. The first one is the eagerly initialized
* instance in {@link IvoryTower}. Eager initialization implies that the implementation is thread * instance in {@link IvoryTower}. Eager initialization implies that the implementation is thread
* safe. If you can afford giving up control of the instantiation moment, then this implementation * safe. If you can afford to give up control of the instantiation moment, then this implementation
* will suit you fine.</p> * will suit you fine.</p>
* *
* <p>The other option to implement eagerly initialized Singleton is enum based Singleton. The * <p>The other option to implement eagerly initialized Singleton is enum-based Singleton. The
* example is found in {@link EnumIvoryTower}. At first glance the code looks short and simple. * example is found in {@link EnumIvoryTower}. At first glance, the code looks short and simple.
* However, you should be aware of the downsides including committing to implementation strategy, * However, you should be aware of the downsides including committing to implementation strategy,
* extending the enum class, serializability and restrictions to coding. These are extensively * extending the enum class, serializability, and restrictions to coding. These are extensively
* discussed in Stack Overflow: http://programmers.stackexchange.com/questions/179386/what-are-the-downsides-of-implementing * discussed in Stack Overflow: http://programmers.stackexchange.com/questions/179386/what-are-the-downsides-of-implementing
* -a-singleton-with-javas-enum</p> * -a-singleton-with-javas-enum</p>
* *
@ -56,7 +56,7 @@ import lombok.extern.slf4j.Slf4j;
* ThreadSafeLazyLoadedIvoryTower} since it doesn't synchronize the whole access method but only the * ThreadSafeLazyLoadedIvoryTower} since it doesn't synchronize the whole access method but only the
* method internals on specific conditions.</p> * method internals on specific conditions.</p>
* *
* <p>Yet another way to implement thread safe lazily initialized Singleton can be found in * <p>Yet another way to implement thread-safe lazily initialized Singleton can be found in
* {@link InitializingOnDemandHolderIdiom}. However, this implementation requires at least Java 8 * {@link InitializingOnDemandHolderIdiom}. However, this implementation requires at least Java 8
* API level to work.</p> * API level to work.</p>
*/ */