0

I have a java class with 4 Maps in it. I want all those Map's to be singleton what is the best way in the following ways. if there is any other better way please suggest

  1. making the class singleton and leaving the variables. That is making the constructor private and creating getInstance method.
  2. making the class singleton and making the variables static. That is making the constructor private and creating getInstance method. making all the methods which deal with these 4 maps static
  3. making class singleton, variables static and making each getmethod check if the map is null/size zero and if it is null/size zero calling the initalize method which will initalize all four maps. <issue here will be 4 maps will have 4 get methods and we need to call synchronized on the initalize method>
user2727493
  • 144
  • 2
  • 4
  • 15
  • 1
    global state is a code smell. Thus the answer is: None of these. Take one step back - the 'best' answer (assuming with 'best' you mean "that code which is likely to be easily testable, hard to write bugs in, easy to 'glance at' (you glance at it and make assumptions about what it does; what are the odds those assumptions are correct), hard to misunderstand, and likely to hold up under changing requirements" - wouldn't be any of these 3 options. – rzwitserloot Jul 17 '22 at 05:51
  • @rzwitserloot what is the best way for my requirement. – user2727493 Jul 17 '22 at 05:55
  • That question is not answerable without knowing what those maps represent, why you need them, and in general the 'point' of your app. The one answer written so far highlights the primary points here: A more extensive treatise on my global state is bad, and one particular answer to the problem (dependency injection). – rzwitserloot Jul 17 '22 at 15:38

1 Answers1

1

At first I recommend reading this question (well, its answer): What are drawbacks or disadvantages of singleton pattern? and this: What is dependency injection?

Singleton pattern is about object existing in a single instance, so that it can be used in multiple places. Problem is not with the concept of a singleton, but how it is frequently implemented (through some statically accessed field/method).

So, what you need is a singleton object, but without all the problems mentioned above.

Therefore in the class (which you want to be a singleton), just define all those maps as normal fields, add all the methods you need as well as its dependencies (that should be injected through constructor).

Once that class is defined, you just need to:

  1. create single object of it
  2. provide it to other objects (that needs access to it) when creating them (ideally through their constructor, or a setter method).

How to implement above two points depends on your application. You basically need a dependency injection system.

  • You can manually implement it, which basically means having a factory method that creates all singleton objects and wires them together).
  • If you use spring, then you can rely on its dependency injection capabilities (In this case you just annotate your singleton with @Component and inject to other components with @Autowired).
  • You can even setup dependency injection yourself using for instance https://github.com/google/guice

However, if it's your first contact with the concept of dependency injection. I recommend implementing it manually, this way you'll understand better how above mentioned dependency injection frameworks work.

Mirek Pluta
  • 7,883
  • 1
  • 32
  • 23
  • Thanks for the response i dont want to use spring singleton feature. my main intention is to make the Map variables in side the class as singleton. if i have to create single object of the class. in the below code is it ok to put maps as non static – user2727493 Jul 17 '22 at 07:48
  • class Test { public static Test instance; private Map map1 = new HashMap<>(); private Map map2 = new HashMap<>(); private Map map3 = new HashMap<>(); private Map map4 = new HashMap<>(); public static getInstance() { if(instance == null) { synchronized(Test.class) { if(map1.size == 0) { initalizemap1(); initalizemap2(); initalizemap3(); } } } } – user2727493 Jul 17 '22 at 07:48