0

Enviroment:

I need to share some kind information (see HashMap) through different part of my code. I think that Singleton could be a perfect design pattern - except for one thing:

Information retrival (read init HashMap and populate it) is demand to another class (MVC). So, my question:

is possible to assign to my Singleton class this information from an external class, if yes, how?

And is a good usage of Singleton design pattern? Otherwise, what could you advise me?

I have a manager class that populates this Hashmap. HashMap contains information about "Users". Now, my manager starts n Threads. Every thread open a connection to db. In Db class handler, I have to check if this query contains users in my HashMap.

So at the moment I have: Manager -> Threads -> DBHandler

I want to avoid to pass my HashMap thourgh every constructor. That's why I thought about a Singleton.

Also, my HashMap, once populated, is just a READ-ONLY Map.

  • What do you mean by "is demand to another class"? – Tulains Córdova Aug 9 '16 at 11:43
  • Considering your edit, does the hasmap is global ? Or is it specific to the group of thread started by the manager ? – Walfrat Aug 9 '16 at 12:13
  • Once populated, is global, I mean it could be. Just store information that needs to all other threads (in read-only). it never changes – Tizianoreica Aug 9 '16 at 12:14
  • I want to avoid to pass my HashMap thourgh every constructor. That's why I thought about a Singleton -- I don't think Singleton does what you think it does. – Robert Harvey Aug 9 '16 at 15:15
  • 2
    I can't help but think that when you come to the place where you need to provide a resource like your HashMap throughout your app, you've probably gone wrong in your design somewhere. – CPerkins Aug 9 '16 at 16:33
1

And is a good usage of Singleton design pattern?

No

The singleton pattern is used to enforce that there can only exist a single, unique instance of a class. You don't explicitly need that. It has the drawback of achieving this by holding a global state. This is what you want.

Do not pick a pattern when you don't need it's prime purpose and instead "need" what is the bad part of the pattern.

If you need global state in your program, there is no need to hide behind the singleton pattern. If you need a global state, go and create a global state.

There are multiple ways to do this without having a simple global variable. You could for example put this task into a specialized module. Most dependency injection containers will feature something like a "SingletonLifetime". This is not a singleton. It just means you get the same instance every time you ask your container for an instance.

Whether you use a dependency injection container or not, make sure you inject this state anywhere you need it, to make your program modular and unit-testable.

5

I would strongly recommend shying away from a singleton if at all possible. If you need your different components to reference the same object, then I would normally look to inject it into each component (preferably during construction).

At the very least it will make unit testing your components so much easier. I would refer you to this SO question/answer, which covers such issues.

You address the issue of possibly injecting this config into every component. I would take a higher level view, and configure your components using this config, and then inject those components e.g. (in Scala, but language largely immaterial here)

val entityDao = new EntityDao(config)
val entityMgr = new EntityManager(entityDao)

thus ensuring your components talk at a 'higher' level of abstraction where possible.

  • Through EVERY construction? That's what I'd like to avoid. I have a Manager that init Readers that init DBHandler and Updaters. Every of this class need this HashMap. It's a READ-ONLY map – Tizianoreica Aug 9 '16 at 12:09
  • If you don't inject your dependencies, then testing will likely suffer. You don't have to inject your low level config - rather inject other components configured appropriately. e.g. an EntityManager may have an EntityDao injected into it. That EntityDao will have been configured in advance – Brian Agnew Aug 9 '16 at 12:16
  • Downvoted the answer because of its form: (1) you barely explain why singletons shouldn't be used—unit testing is only one of the reasons, (2) you made a generalization—there are cases where singletons are a valid approach, and (3) you don't seem to answer in a context of the original question, but rather give a (generalized) recommendation. This reads like: “Never use goto” or “TDD is great”, which doesn't lead to high quality answers. – Arseni Mourzenko Aug 9 '16 at 13:12
  • @MainMa - Well, I would disagree with some of the above, but I'm grateful for a detailed discussion around a downvote, and have amended appropriately. I trust that improves the quality – Brian Agnew Aug 9 '16 at 13:49
  • @BrianAgnew: yes, it's slightly better now. Downvote removed. – Arseni Mourzenko Aug 9 '16 at 15:14
3

You could work it so that the external class defines the singleton, though it wouldn't quite be what people expect from a singleton since it's not always available.

That said, you shouldn't use a singleton for this. Singletons exist to restrict a type to only having a single instance ever. That is an exceptionally rare and limiting design, and nothing you've said makes me think it is warranted here. It seems you just want a global. If that's what you want, just use a global.

  • I thought about Singleton just because my HashMap (once populated) is a ReadOnly Map. But This information needs to be shared thourgh different kind of classes. I want to avoit to pass thorugh construction of every class – Tizianoreica Aug 9 '16 at 12:11
  • 2
    @AntonioCalì - you should not. If your data is coupled to many places, you should either fix that, or make the dependency explicit so that it is more easily supplied/changed/isolated. – Telastyn Aug 9 '16 at 13:40
-1

Singleton pattern is good for keeping config information that various parts of the application might need. That said, it is difficult to write unit tests for it. Therefore, if you absolutely must use singleton in your particular case and dependency injection is out of the question, write a regular class, write unit tests for it, and then just write a singleton wrapper around it, so that you have the best of both worlds.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.