• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Bear Bibeault
  • Junilu Lacar
  • Martin Vashko
Sheriffs:
  • Jeanne Boyarsky
  • Tim Cooke
  • Knute Snortum
Saloon Keepers:
  • Ron McLeod
  • Tim Moores
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
Bartenders:
  • Scott Selikoff
  • salvin francis
  • Piet Souris

Singleton Pattern

 
Ranch Hand
Posts: 125
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dear Friends,

I have a doubt on singleton pattern.

1.singletone object will be stored in the static variable of a class, so this cause the object alive until the class unloaded from the class, isn't it.
2. on the otherhand a object is being created, used and automatically GC collects by the JVM while its no longer referenced.

What will happen when a application use case 1(assume 1000 singleton objects), run on a JVM?
What will happen when a application use case 2, run on a JVM?

The above my question is regarding Memory management.
 
Ranch Hand
Posts: 308
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
static just means, that there is only one instance per (loaded) class per JVM.

the inside of a static variable (if its type is Object) is just a normal object, so it can surely cause an OutOfMemoryError.
it can too be removed from memory, but it only will be when the class gets unloaded and/or JVM gets shutdown.
 
author
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Originally posted by KasiMurugan Ramasamy:
What will happen when a application use case 1(assume 1000 singleton objects), run on a JVM?



I can't imagine an application with 1000 singletons. That would be quite fishy. In fact I use the singleton pattern *very* rarely.
 
Ranch Hand
Posts: 385
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It is very good pattern. The idea is to have single object of its kind. And being able to access it globaly is a plus! So I doubt you will need 1000 of these. Every singleton is a concrete class you can't create more than 1. Regarding your concerns , I think they are too early. You shouldn't concern yourself with memory or performance problems until you really run into them.

The singleton will save you from passing same parameters down the call hierarchy over and over again. In example you have code that deals with some DBManager. Of course you can have every method (or constructor) to accept one and then all methods it calls also will have one and so on and so forth. Is it flexible ? Yes. But still you will have one DBManager for whole application. So it is unecessary effort and it will not contribute to code readability by not using the singleton.

And again about performance. Don't tune it before you really need to and you know where to. Maybe your app will be slowed down because of inefficient database design (much bigger chance), not because it uses 55 singletons.

Example about performace tuning from my job. Some reports where working very slowly. The user had to wait 15 min to get one. So the boss said we have to tune it. The database guy ran through his PL/SQL code and diligently optimized it. Result- 1 week spent, report = 12 mins The idea was he was looking wrong place. He could optimize his code as much as he wanted but because the way tables and relationships were structured it was impossible to get any better than say 8 mins, while the customer said he will wait 2.5 mins max.

Huh Here went my 15 min break Good luck!
 
Vladas Razas
Ranch Hand
Posts: 385
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
1000 singletons... I don't think there is a single application on Earth that uses 1000 singletons. You have 10-20, ok maybe 50 (that's A LOT), but 1000....
 
Vladas Razas
Ranch Hand
Posts: 385
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Unless you love abstract factory pattern combined with singleton. But factories are also overused alot. Here is what my fellow architect sent:

Translated from my native language:

One of our programmers explains me 'look at google. they do everything simple, the more simple it is the better'. I gave him to write a class. What he wrote instead of one class with 5 lines of code - Factory interface, abstract factory, concrete factory, then the class interface and class implementation (with those 5 lines of code).
Great! The man is reading books how to do things better, sees how google does things, attending university (I think MD), explains how to do things simple... and here you see what he does I just can't find right words...

 
Ilja Preuss
author
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Originally posted by Vladas Razas:
And being able to access it globaly is a plus!



I wholeheartedly disagree - global variables already lead to coupling problems in structured programming, they do doubly so in object oriented programming.


The singleton will save you from passing same parameters down the call hierarchy over and over again.



There are other solutions to that problem at lower costs than that of the Singleton pattern.


In example you have code that deals with some DBManager. Of course you can have every method (or constructor) to accept one and then all methods it calls also will have one and so on and so forth. Is it flexible ? Yes. But still you will have one DBManager for whole application. So it is unecessary effort and it will not contribute to code readability by not using the singleton.



It will contribute to the testability, flexibility and reusability of the components. All much more important than having to type a few less key strokes, in my not so humble opinion.

And again about performance. Don't tune it before you really need to and you know where to.



Full agreement here!
 
Vladas Razas
Ranch Hand
Posts: 385
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

There are other solutions to that problem at lower costs than that of the Singleton pattern.



I am intrugued! How to access those DBManagers, Service Locators and alike wihout passing parameters (or using constructors) at low cost?
 
(instanceof Sidekick)
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dependency injection is one neat way. At startup or object creation an application assembler pushes references to those shared resources to objects that need them. The Spring framework does this with very positive effect. Martin Fowler's paper on Inversion of Control Containers and the Dependency Injection pattern describes it in more general terms.
 
Ilja Preuss
author
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, DI is one way.

Another is to instead passing around the DBManager object etc., pass around context objects (basically as containers). That reduces coupling to the classes that are used in only some of the clients.

You might also be able to reduce the need for passing around objects by changing the way your objects collaborate. The problem might just be a symptom for a more basic design problem.

And finally I don't have that much of a problem with passing objects around. Finding a structure where passing the objects around feels natural and fun, that's what OOD is about to me.
 
Vladas Razas
Ranch Hand
Posts: 385
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
But singleton is the most simple of them all! That's the beauty of it. All depends on requirements of course.
 
Ilja Preuss
author
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Originally posted by Vladas Razas:
But singleton is the most simple of them all! That's the beauty of it. All depends on requirements of course.



The point is that requirements change. Every successful system needs to be maintained and extended for years, if not decades. You don't know what requirements will emerge during that time. That's why it's important to manage the dependencies of the code to keep it flexible.

The problem with the Singleton pattern is that typically with the time *a lot* of code directly accesses it (that's what the global access point is good for, isn't it). That makes it immensely costly to later change it should you suddenly require several different instances.

Another problem that actually emerges immediately is that Singletons complicate unit testing quite a lot.
 
Stan James
(instanceof Sidekick)
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

pass around context objects (basically as containers)



I did that in my Wiki, but I have to say I felt dirty about it. It seemed to be some admission that I didn't really know what object was going to need what parameters in the future. Do you know if it's consider A Good Thing or not?

*a lot* of code directly accesses it (that's what the global access point is good for, isn't it)



It seems you can get around this by saying the global access point (static method) is a creator method that can return any implementation of some interface and just happens to create only one instance at a time. Or maybe that's not Singleton any more? From the outside it would be hard to tell if it used Singleton or Just Create One internally.
 
Ilja Preuss
author
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Originally posted by Stan James:
I did that in my Wiki, but I have to say I felt dirty about it. It seemed to be some admission that I didn't really know what object was going to need what parameters in the future. Do you know if it's consider A Good Thing or not?



I don't consider feeling dirty a good thing...

Besides that, no, I have no final word on that pattern.

In my experience, though, it can work quite well when you take care that the context objects are just used for one coherent task (for example by having a ReportCreationContext) and you take care that they don't become too big.



It seems you can get around this by saying the global access point (static method) is a creator method that can return any implementation of some interface and just happens to create only one instance at a time. Or maybe that's not Singleton any more? From the outside it would be hard to tell if it used Singleton or Just Create One internally.



I'm not sure I understand what you are getting at here. Are you suggesting to simply not access the global access point globally, or something else?
 
Vladas Razas
Ranch Hand
Posts: 385
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

The point is that requirements change. Every successful system needs to be maintained and extended for years, if not decades. You don't know what requirements will emerge during that time. That's why it's important to manage the dependencies of the code to keep it flexible.



That's an investment! In my project we use old, limited functionality, buggy domain store (something ala Hibernate, but I wish it would be Hibernate). I would love to switch to Hibernate. The singleton we use to access our SQLManager is very small part of the problem. Even if it would not be singleton, still the whole system depends on custom relation mapping file, and API.
I think what you suggest is a upfront system design. That is one has to think through all design issues that may change and do it very flexible. Make big investments in code flexibility. However with rapidly changing systems there no doubt will be problems even with most flexible designs. And this investing thing is like, setting things in stone: "this can change and this not".
 
Vladas Razas
Ranch Hand
Posts: 385
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Also we can staticaly replace one implementation of singleton with another. If half code needs to use one implementation, then half another, we can just make another singleton. Of course if we need dynamicaly decide on what code to use then DI is good (or other ways available)!
Contexts can get dirty if not to be very careful. At some point people will start passing contexts even if the code does not require all things in context so the code will couple with classes it will not even use. We could pass maps with parameters like HttpServletRequest is. But in this case we are saying goodbye to compiler parameters checking. Which is very nice to have.
But again my opinion is that singletons, DI, context they are good tools at the right time.
 
Ilja Preuss
author
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Originally posted by Vladas Razas:
That's an investment!



A small one, I would say.

And in fact, as I said, when I want to unit test my classes, singletons tend to make it more complicated, anyway.

I think what you suggest is a upfront system design. That is one has to think through all design issues that may change and do it very flexible.



I think is what I suggest is thinking about basic design principles, such as managing coupling and cohesion. And to apply them sensibly.

To me, applying the Singleton pattern is most often a violation of the Single Responsibility Principle - a class typically shouldn't know about how many instances of itself are used in a system, that should be the responsibility of someone else.

I don't think of applying such principles as an investment, I think of *not* applying them as debt: http://www.jamesshore.com/Articles/Business/Software%20Profitability%20Newsletter/Design%20Debt.html

And yes, I can imagine that in your system there are more problems than the use of the Singleton pattern - I'm working on such systems, too.

But to me that just means that we should probably invest *more* in code quality, not less...
 
Ilja Preuss
author
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Originally posted by Vladas Razas:

However with rapidly changing systems there no doubt will be problems even with most flexible designs. And this investing thing is like, setting things in stone: "this can change and this not".



Yes. That is, of course, the whole art of design:

Finding a balance between the cost of a design, the likeliness of needing the flexibility, the cost of introducing the change later and the probability that the flexibility we'd introduce now is the one we will need later.

Regarding the Singleton pattern, see also http://butunclebob.com/ArticleS.UncleBob.SingletonVsJustCreateOne
 
Stan James
(instanceof Sidekick)
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

I'm not sure I understand what you are getting at here. Are you suggesting to simply not access the global access point globally, or something else?



I was suggesting establishing the actual implementation class for the singleton through configuration or injection. But I'm not sure where this turns into Just Create One instead.

Under benefits GoF says things like "The singleton class may be subclassed and it's easy to configure an application with an instance of this extended class. You can configure the application with an instance of the class you need at run-time." Under implementation they have another page and a half about subclassing, registries, etc. These give you permission to solve your unit testing issues, no?

BTW: That "art of design" post really nailed it.
[ August 19, 2006: Message edited by: Stan James ]
 
Ilja Preuss
author
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Originally posted by Stan James:
I was suggesting establishing the actual implementation class for the singleton through configuration or injection.



I see. So you would still have the global access point, right?


But I'm not sure where this turns into Just Create One instead.



I guess it wouldn't - for that, you would have to get rid of the global access point, I'd feel.


Under benefits GoF says things like "The singleton class may be subclassed and it's easy to configure an application with an instance of this extended class. You can configure the application with an instance of the class you need at run-time." Under implementation they have another page and a half about subclassing, registries, etc. These give you permission to solve your unit testing issues, no?



I actually tried that for quite a time - simply adding a setTestInstance method to my singletons (yes, I have quite some experience with the Singleton pattern).

In my experience, it doesn't really work that well. I often forgot to reset the Singleton in tearDown. Half a year later, suddenly some tests would fail because other classes depended on the Singleton, whichs tests didn't take care of it - and the execution order had changed, so that the Singleton suddenly was in a different state for those tests.

With other words, with a Singleton in your design, it's really hard to make your unit tests fully independent of each other. I *hate* that!


BTW: That "art of design" post really nailed it.



Thanks! I probably stole it from Robert C. Martin, Ron Jeffries or someone...

One thing I forgot to mention is that to me, a design is *never* set in stone - I *always* can (and have to) refactor it. (You will probably agree.)

It's just that with a Singleton present, it's much less fun than it could be, in my experience...
 
Stan James
(instanceof Sidekick)
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think we're on the same page. I'll agree that Singleton has the potential to add effort and grief for the more sophisticated configuration and testability things you're running into.
 
The City calls upon her steadfast protectors. Now for a tiny ad:
Java file APIs (DOC, XLS, PDF, and many more)
https://products.aspose.com/total/java
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!