Storing singleton instances in a generic utils class
up vote
0
down vote
favorite
In one of my java projects I use singletons a lot and I was looking for a way to reduce repeating code. I made a SingletonUtils
class that accepts a class and supplier parameter. Then stores the instance in a hash map. This way the static instance isn't stored as a static variable in the class I want to make a singleton.
My question is, is there any problems/cons with implementing the singleton pattern like this and is there an easier way to do this or is this the best way?
public class SingletonUtils {
public static HashMap<Class, Object> instances = new HashMap<>();
public static <T> T getInstance(final Class<T> singletonObj, final Supplier<T> creator) {
if(!instances.containsKey(singletonObj)) {
if(creator == null) return null;
else instances.put(singletonObj, creator.get());
}
return (T) instances.get(singletonObj);
}
public static boolean instanceExists(final Class singletonObj) {
return instances.containsKey(singletonObj);
}
public static void removeInstance(final Class singletonObj) {
instances.remove(singletonObj);
}
}
public final class AuthManager {
private AuthManager() { }
public static AuthManager getNewInstance() {
return SingletonUtils.getInstance(AuthManager.class, AuthManager::new);
}
}
java singleton
add a comment |
up vote
0
down vote
favorite
In one of my java projects I use singletons a lot and I was looking for a way to reduce repeating code. I made a SingletonUtils
class that accepts a class and supplier parameter. Then stores the instance in a hash map. This way the static instance isn't stored as a static variable in the class I want to make a singleton.
My question is, is there any problems/cons with implementing the singleton pattern like this and is there an easier way to do this or is this the best way?
public class SingletonUtils {
public static HashMap<Class, Object> instances = new HashMap<>();
public static <T> T getInstance(final Class<T> singletonObj, final Supplier<T> creator) {
if(!instances.containsKey(singletonObj)) {
if(creator == null) return null;
else instances.put(singletonObj, creator.get());
}
return (T) instances.get(singletonObj);
}
public static boolean instanceExists(final Class singletonObj) {
return instances.containsKey(singletonObj);
}
public static void removeInstance(final Class singletonObj) {
instances.remove(singletonObj);
}
}
public final class AuthManager {
private AuthManager() { }
public static AuthManager getNewInstance() {
return SingletonUtils.getInstance(AuthManager.class, AuthManager::new);
}
}
java singleton
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
In one of my java projects I use singletons a lot and I was looking for a way to reduce repeating code. I made a SingletonUtils
class that accepts a class and supplier parameter. Then stores the instance in a hash map. This way the static instance isn't stored as a static variable in the class I want to make a singleton.
My question is, is there any problems/cons with implementing the singleton pattern like this and is there an easier way to do this or is this the best way?
public class SingletonUtils {
public static HashMap<Class, Object> instances = new HashMap<>();
public static <T> T getInstance(final Class<T> singletonObj, final Supplier<T> creator) {
if(!instances.containsKey(singletonObj)) {
if(creator == null) return null;
else instances.put(singletonObj, creator.get());
}
return (T) instances.get(singletonObj);
}
public static boolean instanceExists(final Class singletonObj) {
return instances.containsKey(singletonObj);
}
public static void removeInstance(final Class singletonObj) {
instances.remove(singletonObj);
}
}
public final class AuthManager {
private AuthManager() { }
public static AuthManager getNewInstance() {
return SingletonUtils.getInstance(AuthManager.class, AuthManager::new);
}
}
java singleton
In one of my java projects I use singletons a lot and I was looking for a way to reduce repeating code. I made a SingletonUtils
class that accepts a class and supplier parameter. Then stores the instance in a hash map. This way the static instance isn't stored as a static variable in the class I want to make a singleton.
My question is, is there any problems/cons with implementing the singleton pattern like this and is there an easier way to do this or is this the best way?
public class SingletonUtils {
public static HashMap<Class, Object> instances = new HashMap<>();
public static <T> T getInstance(final Class<T> singletonObj, final Supplier<T> creator) {
if(!instances.containsKey(singletonObj)) {
if(creator == null) return null;
else instances.put(singletonObj, creator.get());
}
return (T) instances.get(singletonObj);
}
public static boolean instanceExists(final Class singletonObj) {
return instances.containsKey(singletonObj);
}
public static void removeInstance(final Class singletonObj) {
instances.remove(singletonObj);
}
}
public final class AuthManager {
private AuthManager() { }
public static AuthManager getNewInstance() {
return SingletonUtils.getInstance(AuthManager.class, AuthManager::new);
}
}
java singleton
java singleton
edited Nov 14 at 13:45
asked Nov 14 at 11:52
Josh Gager
206
206
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
up vote
5
down vote
accepted
Let me just express the first thing that came to mind when I read this question's title:
Not another Singleton question.
Let's ignore in the following that Singletons are an anti-pattern in Object-Oriented Programming.
Look. I get it. Singletons are nice and easy.
Everything about them makes things easier to think about.
The whole point of a singleton is that only one instance of it ever exists.
It's by definition the single source of truth.
What your code does is subtly, but completely undermine that assumption.
Consider the following sequence:
AuthManager authSingleton = AuthManager.getNewInstance();
SingletonUtils.removeInstance(AuthManager.class),
AuthManager anotherSingleton = AuthManager.getNewInstance();
Those don't need to be in the same thread, the same class or the same anything. As long as they run in the same JVM, authSingleton == anotherSingleton
will be false. And this is a complete and utter breakage of the semantics of a Singleton.
What you tried to do with that class is not something that you want. You're centrally controlling the lifetime of singletons. But you're not correctly enforcing the semantics of these singletons.
This code is something like an ObjectPool. Implying that it has anything to do with singletons is incorrect though.
Do not make singletons complicated:
public final class AuthManager {
private static final AuthManager INSTANCE = new AuthManager();
public static AuthManager get() {
return INSTANCE;
}
private AuthManager() {
}
}
^^ This is a complete, threadsafe and lazily initialized Singleton. In 99.9999% of the use-cases of a singleton, this is enough. But 90% of all Singleton uses are just flat out wrong.
There is no useful reason for an "AuthManager" to be a Singleton. Don't cargo-cult.
1
This helped a lot, thanks, I will be changing the AuthManager to not be a singleton. Before now I didn't think of the case where the system may need to use multiple databases for the auth system and thus need multiple instances of the AuthManager. I'm going to rethink all my singleton usage in the future as you are right I probably don't need them in most situations.
– Josh Gager
Nov 14 at 13:02
add a comment |
up vote
2
down vote
I agree with Vogel612 - Singleton is an anti-pattern because of nomerous reasons. Just don't.
However I want to mention the pattern "ServiceLocator" because it is very similar to your question. Maybe you want to read about it. But - just like the Singleton - the ServiceLocator is widely known as an anti-pattern.
New contributor
3
If both are known as anti-patterns, isn't it trading one problem for another?
– Mast
Nov 14 at 13:46
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
5
down vote
accepted
Let me just express the first thing that came to mind when I read this question's title:
Not another Singleton question.
Let's ignore in the following that Singletons are an anti-pattern in Object-Oriented Programming.
Look. I get it. Singletons are nice and easy.
Everything about them makes things easier to think about.
The whole point of a singleton is that only one instance of it ever exists.
It's by definition the single source of truth.
What your code does is subtly, but completely undermine that assumption.
Consider the following sequence:
AuthManager authSingleton = AuthManager.getNewInstance();
SingletonUtils.removeInstance(AuthManager.class),
AuthManager anotherSingleton = AuthManager.getNewInstance();
Those don't need to be in the same thread, the same class or the same anything. As long as they run in the same JVM, authSingleton == anotherSingleton
will be false. And this is a complete and utter breakage of the semantics of a Singleton.
What you tried to do with that class is not something that you want. You're centrally controlling the lifetime of singletons. But you're not correctly enforcing the semantics of these singletons.
This code is something like an ObjectPool. Implying that it has anything to do with singletons is incorrect though.
Do not make singletons complicated:
public final class AuthManager {
private static final AuthManager INSTANCE = new AuthManager();
public static AuthManager get() {
return INSTANCE;
}
private AuthManager() {
}
}
^^ This is a complete, threadsafe and lazily initialized Singleton. In 99.9999% of the use-cases of a singleton, this is enough. But 90% of all Singleton uses are just flat out wrong.
There is no useful reason for an "AuthManager" to be a Singleton. Don't cargo-cult.
1
This helped a lot, thanks, I will be changing the AuthManager to not be a singleton. Before now I didn't think of the case where the system may need to use multiple databases for the auth system and thus need multiple instances of the AuthManager. I'm going to rethink all my singleton usage in the future as you are right I probably don't need them in most situations.
– Josh Gager
Nov 14 at 13:02
add a comment |
up vote
5
down vote
accepted
Let me just express the first thing that came to mind when I read this question's title:
Not another Singleton question.
Let's ignore in the following that Singletons are an anti-pattern in Object-Oriented Programming.
Look. I get it. Singletons are nice and easy.
Everything about them makes things easier to think about.
The whole point of a singleton is that only one instance of it ever exists.
It's by definition the single source of truth.
What your code does is subtly, but completely undermine that assumption.
Consider the following sequence:
AuthManager authSingleton = AuthManager.getNewInstance();
SingletonUtils.removeInstance(AuthManager.class),
AuthManager anotherSingleton = AuthManager.getNewInstance();
Those don't need to be in the same thread, the same class or the same anything. As long as they run in the same JVM, authSingleton == anotherSingleton
will be false. And this is a complete and utter breakage of the semantics of a Singleton.
What you tried to do with that class is not something that you want. You're centrally controlling the lifetime of singletons. But you're not correctly enforcing the semantics of these singletons.
This code is something like an ObjectPool. Implying that it has anything to do with singletons is incorrect though.
Do not make singletons complicated:
public final class AuthManager {
private static final AuthManager INSTANCE = new AuthManager();
public static AuthManager get() {
return INSTANCE;
}
private AuthManager() {
}
}
^^ This is a complete, threadsafe and lazily initialized Singleton. In 99.9999% of the use-cases of a singleton, this is enough. But 90% of all Singleton uses are just flat out wrong.
There is no useful reason for an "AuthManager" to be a Singleton. Don't cargo-cult.
1
This helped a lot, thanks, I will be changing the AuthManager to not be a singleton. Before now I didn't think of the case where the system may need to use multiple databases for the auth system and thus need multiple instances of the AuthManager. I'm going to rethink all my singleton usage in the future as you are right I probably don't need them in most situations.
– Josh Gager
Nov 14 at 13:02
add a comment |
up vote
5
down vote
accepted
up vote
5
down vote
accepted
Let me just express the first thing that came to mind when I read this question's title:
Not another Singleton question.
Let's ignore in the following that Singletons are an anti-pattern in Object-Oriented Programming.
Look. I get it. Singletons are nice and easy.
Everything about them makes things easier to think about.
The whole point of a singleton is that only one instance of it ever exists.
It's by definition the single source of truth.
What your code does is subtly, but completely undermine that assumption.
Consider the following sequence:
AuthManager authSingleton = AuthManager.getNewInstance();
SingletonUtils.removeInstance(AuthManager.class),
AuthManager anotherSingleton = AuthManager.getNewInstance();
Those don't need to be in the same thread, the same class or the same anything. As long as they run in the same JVM, authSingleton == anotherSingleton
will be false. And this is a complete and utter breakage of the semantics of a Singleton.
What you tried to do with that class is not something that you want. You're centrally controlling the lifetime of singletons. But you're not correctly enforcing the semantics of these singletons.
This code is something like an ObjectPool. Implying that it has anything to do with singletons is incorrect though.
Do not make singletons complicated:
public final class AuthManager {
private static final AuthManager INSTANCE = new AuthManager();
public static AuthManager get() {
return INSTANCE;
}
private AuthManager() {
}
}
^^ This is a complete, threadsafe and lazily initialized Singleton. In 99.9999% of the use-cases of a singleton, this is enough. But 90% of all Singleton uses are just flat out wrong.
There is no useful reason for an "AuthManager" to be a Singleton. Don't cargo-cult.
Let me just express the first thing that came to mind when I read this question's title:
Not another Singleton question.
Let's ignore in the following that Singletons are an anti-pattern in Object-Oriented Programming.
Look. I get it. Singletons are nice and easy.
Everything about them makes things easier to think about.
The whole point of a singleton is that only one instance of it ever exists.
It's by definition the single source of truth.
What your code does is subtly, but completely undermine that assumption.
Consider the following sequence:
AuthManager authSingleton = AuthManager.getNewInstance();
SingletonUtils.removeInstance(AuthManager.class),
AuthManager anotherSingleton = AuthManager.getNewInstance();
Those don't need to be in the same thread, the same class or the same anything. As long as they run in the same JVM, authSingleton == anotherSingleton
will be false. And this is a complete and utter breakage of the semantics of a Singleton.
What you tried to do with that class is not something that you want. You're centrally controlling the lifetime of singletons. But you're not correctly enforcing the semantics of these singletons.
This code is something like an ObjectPool. Implying that it has anything to do with singletons is incorrect though.
Do not make singletons complicated:
public final class AuthManager {
private static final AuthManager INSTANCE = new AuthManager();
public static AuthManager get() {
return INSTANCE;
}
private AuthManager() {
}
}
^^ This is a complete, threadsafe and lazily initialized Singleton. In 99.9999% of the use-cases of a singleton, this is enough. But 90% of all Singleton uses are just flat out wrong.
There is no useful reason for an "AuthManager" to be a Singleton. Don't cargo-cult.
answered Nov 14 at 12:32
Vogel612♦
21.3k346128
21.3k346128
1
This helped a lot, thanks, I will be changing the AuthManager to not be a singleton. Before now I didn't think of the case where the system may need to use multiple databases for the auth system and thus need multiple instances of the AuthManager. I'm going to rethink all my singleton usage in the future as you are right I probably don't need them in most situations.
– Josh Gager
Nov 14 at 13:02
add a comment |
1
This helped a lot, thanks, I will be changing the AuthManager to not be a singleton. Before now I didn't think of the case where the system may need to use multiple databases for the auth system and thus need multiple instances of the AuthManager. I'm going to rethink all my singleton usage in the future as you are right I probably don't need them in most situations.
– Josh Gager
Nov 14 at 13:02
1
1
This helped a lot, thanks, I will be changing the AuthManager to not be a singleton. Before now I didn't think of the case where the system may need to use multiple databases for the auth system and thus need multiple instances of the AuthManager. I'm going to rethink all my singleton usage in the future as you are right I probably don't need them in most situations.
– Josh Gager
Nov 14 at 13:02
This helped a lot, thanks, I will be changing the AuthManager to not be a singleton. Before now I didn't think of the case where the system may need to use multiple databases for the auth system and thus need multiple instances of the AuthManager. I'm going to rethink all my singleton usage in the future as you are right I probably don't need them in most situations.
– Josh Gager
Nov 14 at 13:02
add a comment |
up vote
2
down vote
I agree with Vogel612 - Singleton is an anti-pattern because of nomerous reasons. Just don't.
However I want to mention the pattern "ServiceLocator" because it is very similar to your question. Maybe you want to read about it. But - just like the Singleton - the ServiceLocator is widely known as an anti-pattern.
New contributor
3
If both are known as anti-patterns, isn't it trading one problem for another?
– Mast
Nov 14 at 13:46
add a comment |
up vote
2
down vote
I agree with Vogel612 - Singleton is an anti-pattern because of nomerous reasons. Just don't.
However I want to mention the pattern "ServiceLocator" because it is very similar to your question. Maybe you want to read about it. But - just like the Singleton - the ServiceLocator is widely known as an anti-pattern.
New contributor
3
If both are known as anti-patterns, isn't it trading one problem for another?
– Mast
Nov 14 at 13:46
add a comment |
up vote
2
down vote
up vote
2
down vote
I agree with Vogel612 - Singleton is an anti-pattern because of nomerous reasons. Just don't.
However I want to mention the pattern "ServiceLocator" because it is very similar to your question. Maybe you want to read about it. But - just like the Singleton - the ServiceLocator is widely known as an anti-pattern.
New contributor
I agree with Vogel612 - Singleton is an anti-pattern because of nomerous reasons. Just don't.
However I want to mention the pattern "ServiceLocator" because it is very similar to your question. Maybe you want to read about it. But - just like the Singleton - the ServiceLocator is widely known as an anti-pattern.
New contributor
New contributor
answered Nov 14 at 13:07
Alex
1211
1211
New contributor
New contributor
3
If both are known as anti-patterns, isn't it trading one problem for another?
– Mast
Nov 14 at 13:46
add a comment |
3
If both are known as anti-patterns, isn't it trading one problem for another?
– Mast
Nov 14 at 13:46
3
3
If both are known as anti-patterns, isn't it trading one problem for another?
– Mast
Nov 14 at 13:46
If both are known as anti-patterns, isn't it trading one problem for another?
– Mast
Nov 14 at 13:46
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f207649%2fstoring-singleton-instances-in-a-generic-utils-class%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown