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);
}
}









share|improve this question




























    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);
    }
    }









    share|improve this question


























      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);
      }
      }









      share|improve this question















      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






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 14 at 13:45

























      asked Nov 14 at 11:52









      Josh Gager

      206




      206






















          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.






          share|improve this answer

















          • 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


















          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.






          share|improve this answer








          New contributor




          Alex is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.














          • 3




            If both are known as anti-patterns, isn't it trading one problem for another?
            – Mast
            Nov 14 at 13:46











          Your Answer





          StackExchange.ifUsing("editor", function () {
          return StackExchange.using("mathjaxEditing", function () {
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          });
          });
          }, "mathjax-editing");

          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "196"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














           

          draft saved


          draft discarded


















          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

























          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.






          share|improve this answer

















          • 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















          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.






          share|improve this answer

















          • 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













          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.






          share|improve this answer












          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.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          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














          • 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












          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.






          share|improve this answer








          New contributor




          Alex is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.














          • 3




            If both are known as anti-patterns, isn't it trading one problem for another?
            – Mast
            Nov 14 at 13:46















          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.






          share|improve this answer








          New contributor




          Alex is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.














          • 3




            If both are known as anti-patterns, isn't it trading one problem for another?
            – Mast
            Nov 14 at 13:46













          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.






          share|improve this answer








          New contributor




          Alex is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.









          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.







          share|improve this answer








          New contributor




          Alex is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.









          share|improve this answer



          share|improve this answer






          New contributor




          Alex is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.









          answered Nov 14 at 13:07









          Alex

          1211




          1211




          New contributor




          Alex is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.





          New contributor





          Alex is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.






          Alex is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.








          • 3




            If both are known as anti-patterns, isn't it trading one problem for another?
            – Mast
            Nov 14 at 13:46














          • 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


















           

          draft saved


          draft discarded



















































           


          draft saved


          draft discarded














          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





















































          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







          Popular posts from this blog

          Сан-Квентин

          Алькесар

          8-я гвардейская общевойсковая армия