• 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 Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Combining State and Singleton design patterns

 
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi folks,

I'm using the State design pattern to handle state changes within my client-side UI. Most of the design pattern text books (including GoF) suggest that it makes sense:
a) to make each State an inner class (so that it can access variables within the parent "Context" class)
b) optionally, also to make each State class a Singleton

OK, I agree with them. But here's the problem...

A Singleton generally makes use of a static instance of itself, accessed via a static getInstance() method. BUT static declarations aren't allowed within an inner class. The immediately obvious solutions are:
1) don't use a Singleton for each State (but that loses some efficiency/encapsulation benefits that I'd like to retain)
2) make each State a stand-alone class (but then I've lost the benefits of access to the parent "Context" class)
3) make each State a static nested class (no obvious major benefit over option 2)

Anyone got any ideas? Am I missing an obvious solution?

Thanks in advance
 
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


...static declarations aren't allowed within an inner class...



A singleton is a regular object accessed via its class' static method (getInstance).

Take a look at this piece of code I wrote:

 
Ranch Hand
Posts: 197
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


You do not need to do this, a static member is initialised once on 1st access, so you can just do:


[ July 16, 2004: Message edited by: mike acre ]
 
John Cozens
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Guys, thanks for your quick replies.

Pedro
=====
OK Pedro, that's a neat trick. So effectively you're using Inner to act as a "Singleton wrapper"? Which means that Inner can get access to Outer's members, although Singleton itself still can't (unless you use x to get values from Outer then mail them across to Singleton using a getXXX() method?). Hmm, so are there still a couple of issues:
i) for every Singleton I now have to create 2 classes - 1 original stand-alone (Singleton) and a "wrapper" (Inner) buried within the ultimate parent (Outer)? That doesn't seem ideal but, agreed, it does work;
ii) to keep as much encapsulation as possible, let's say I want to put lots of state-based methods in Singleton, which in turn need to set/un-set GUI components within Outer. As Singleton is outside the scope of Outer, it still doesn't have access to Outer's members. In this case, would you need to add all of the relevant GUI-changing methods to Inner instead? If that's so, have you then defeated the point of having a Singleton in the first place? Although your Singleton is a genuine Singleton, Inner is not.

So thanks for the solution, it's really interesting. Any further thoughts on these secondary issues would definitely be welcome


Mike
====
Thanks Mike. I reckon you and Pedro are both right - these are merely different solutions to achieving a Singleton. Yours is definitely more appropriate when you want to instantiate your Singleton up-front (say during initialisation while the user's looking at a dazzling splash screen ), while Pedro's is more appropriate when you want to use "lazy instantiation"...that means you want your Singleton built on a "Just in Time" basis, the first time that getInstance() is called, and not a moment sooner. That can be useful if say you've got 10 million potential Singleton Objects, of which you'll probably only ever need 50 during a typical program run, but you don't know which ones you'll need in advance.

Best

John
 
John Cozens
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Sorry Pedro, I meant a setXXX() method, not getXXX(), for example using something like x.setState(outerVariableValue) as a mechanism for getting info about one of Outer's member variables to your Singleton instance.
 
Pedro Penna
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
John,

I think you should use Inner Classes OR the Singleton pattern in this case.

You could also use something similar to the "Typesafe Enum"
pattern discussed in Joshua Bloch's book "Effective Java Guide".


[ July 16, 2004: Message edited by: Pedro Penna ]
 
mike acre
Ranch Hand
Posts: 197
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by John Cozens:

Mike
====
Thanks Mike. I reckon you and Pedro are both right - these are merely different solutions to achieving a Singleton. Yours is definitely more appropriate when you want to instantiate your Singleton up-front (say during initialisation while the user's looking at a dazzling splash screen ), while Pedro's is more appropriate when you want to use "lazy instantiation"...that means you want your Singleton built on a "Just in Time" basis, the first time that getInstance() is called, and not a moment sooner. That can be useful if say you've got 10 million potential Singleton Objects, of which you'll probably only ever need 50 during a typical program run, but you don't know which ones you'll need in advance.



To use a singleton you must get that instance
if you get that instance you access the class
if you access the class you cause any static member to be initialised
(if 1st access). The staic member won't be initialised sooner, since this is a singleton and the 1st access to the class will be to getInstance().
This is lazy instantiation. You can't be lazier with a singleton.
 
Author
Posts: 36
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Note that when using singletons it is important to make them thread safe. I think the best way to do this is like this:



This way the code is both thread-safe and lazy-loading. It doesn't use the common solution, which is to make a getInstance method, and make it synchronized. But that can hurt performance, especially since the call only needs to be synchronized the first time.
 
John Cozens
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Pedro, while experimenting last night I did end up with something not too different from your suggestion, so thanks for that. I have Joshua Bloch's book, so I'll definitely take a look at Item 21 on typesafe enums.


Mike, OK but what if you have a variable within some other class of type Singleton (which you don't plan to instantiate by using Singleton.getInstance() for the next few days). Given that the static variable "instance" in Singleton is, well, static, won't it get initialised during class-loading? So if you use this form:



...that's fine, 'instance' will remain null until another class calls getInstance() on it. But if you use this form instead:



...then 'instance' will actually become an object of type Singleton as a result of class-loading, regardless of whether another class ever calls getInstance() on it or not? I'm not sure we're actually disagreeing on this, I'm just trying to be totally clear in my own mind.


Eben, thanks, I hadn't seen that approach before. I'd pondered using double-checked locking, although opinion seems to vary widely on whether that's totally safe. I'll go away and experiment with the different alternatives.
 
mike acre
Ranch Hand
Posts: 197
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by John Cozens:

Mike, OK but what if you have a variable within some other class of type Singleton (which you don't plan to instantiate by using Singleton.getInstance() for the next few days). Given that the static variable "instance" in Singleton is, well, static, won't it get initialised during class-loading? So if you use this form:




'Of type Singleton' ?

So a subclass of Singleton?
How can you have a subclass if the default constructor is private?




...then 'instance' will actually become an object of type Singleton as a result of class-loading, regardless of whether another class ever calls getInstance() on it or not? I'm not sure we're actually disagreeing on this, I'm just trying to be totally clear in my own mind.



That is correct.
 
John Cozens
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Mike,


'Of type Singleton' ?

So a subclass of Singleton?
How can you have a subclass if the default constructor is private?



No, I agree with you, my fault for not explaining clearly. What I meant was that if you had some code like this...



...then if you ran MyMainClass, your Singleton class would be loaded immediately, before even the first line of main() was run, regardless of whether MyMainClass ever actually called Singleton.getInstance(). Therefore, if you used the second version of Singleton from my last post...



...Singleton.instance would exist as an Object as soon as your app ran, given that it's a class (static) variable within Singleton. Using the other method, this doesn't happen. Singleton.instance remains null until another class calls getInstance() for the first time. At least, this is what my debugger is telling me. So if you did have a million classes that used the above form of Singleton, I'd expect that you'd have constructed a million Objects on start-up, regardless of whether you ever called getInstance() on any of them during the course of the app. They'd just sit there, presumably consuming space on the heap.
 
mike acre
Ranch Hand
Posts: 197
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

So if you did have a million classes that used the above form of Singleton, I'd expect that you'd have constructed a million Objects on start-up, regardless of whether you ever called getInstance() on any of them during the course of the app. They'd just sit there, presumably consuming space on the heap.



No, you'd only have one, the constructor is private and the only instantiation of the object is within a static member, so there can only be one object. Whatever you do outside the class all references will point to that one object. I'm afraid there is NO advantage of doing the usual 'if null' construct for a Java singleton.
 
reply
    Bookmark Topic Watch Topic
  • New Topic