Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (477)
Games in Android Showcase (109)
games submitted by our members
Games in WIP (536)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Static Reference to Self  (Read 1337 times)
0 Members and 1 Guest are viewing this topic.
Offline penguin_buddha

Senior Newbie





« Posted 2013-08-19 22:32:59 »

1  
2  
3  
4  
5  
6  
7  
8  
public class A {

   public static A current;

   public A() {
      current = this;
   }
}


I'm considering doing something like the above and was wondering if this kind of thing is frowned upon and why. The reason i'm doing it is because I know there will only ever be one instance of the class A for each instance of my program and almost all classes need to be able to interact with the instance of class A. So I figured this would be a simpler approach than creating all the other classes with a pointer to the only instance of class A.

Thanks for any help,
Nathan
Offline quew8

JGO Coder


Medals: 29



« Reply #1 - Posted 2013-08-19 22:36:54 »

Why not make the whole class (methods and fields) static. The constructor can either be a static block or an initializer method if you need parameters.
Offline BurntPizza
« Reply #2 - Posted 2013-08-19 22:38:52 »

This scenario is exactly why the Singleton design pattern exists.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline sproingie

JGO Kernel


Medals: 202



« Reply #3 - Posted 2013-08-19 22:42:33 »

That's called a Singleton.  There's room for a lot of opinions on their usefulness, but if you're going to use one, I recommend doing it right.  First, don't put the singleton logic in the constructor, period.  In fact, the constructor has to be private if you're going to prevent new instances from being created.  Second, there's all kinds of funky wrinkles involved if you're ever going to access your singleton in multiple threads.  But last, there's a really easy way to make a singleton: make it an Enum

http://stackoverflow.com/questions/70689/what-is-an-efficient-way-to-implement-a-singleton-pattern-in-java
Offline namrog84

JGO Ninja


Medals: 46
Projects: 4


Keep programming!


« Reply #4 - Posted 2013-08-19 22:45:26 »

Exactly what Sproingie and BurntPizza said

You'd want something like maybe? I am not sure if its better to new in getInstance or at beginning of declaration

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
public class A{
        private static A instance = null;
 
        private A() {       }
 
        public static synchronized A getInstance() {
                if (instance == null) {
                        instance = new A();
                }
                return instance;
        }
}

I am not 100% sure if it has to be synchronized? Someone more qualified can answer that


Anytime you need an acces of your singleton you'd just do

A someAAccessor = A.getInstance();

Or alternatively, you could just make everything static and access them directly without ever creating an instance

"Experience is what you get when you did not get what you wanted"
Offline sproingie

JGO Kernel


Medals: 202



« Reply #5 - Posted 2013-08-19 22:51:28 »

It has to be synchronized if you use it from multiple threads, which you should pretty much assume you always do unless you make things explicitly thread-local.
Offline penguin_buddha

Senior Newbie





« Reply #6 - Posted 2013-08-19 22:53:03 »

Thanks for all the quick responses. I'll look into the singleton pattern.

Out of curiosity do you use the singleton pattern for your primary class for your games?




Thanks,
Nathan
Offline Jeremy
« Reply #7 - Posted 2013-08-19 22:55:36 »

Thanks for all the quick responses. I'll look into the singleton pattern.

Out of curiosity do you use the singleton pattern for your primary class for your games?




Thanks,
Nathan

Why don't you just store it in a global variable so you don't end up designing a class so only one instance of it can exist? It could save you some design head-aches later - and maybe (probably) even some arguments with other programmers.

Singletons are highly controversial, global variables aren't (as controversial) - stressing the 'as' as subjective though. My perspective is while you do have a lot of the negatives that come with singletons come along with globals, at least it doesn't encourage you to design that class as if it is the only one that exists.

Optimally though, it would be better to pass the object around rather than store it globally. It makes it more difficult to extract code etc. Even if you think you'll only ever have one instance.

Personally, I avoid singletons.

JevaEngine, Latest Playthrough (This demo is networked with a centralized server model)

http://www.youtube.com/watch?v=rWA8bajpVXg
Offline Danny02
« Reply #8 - Posted 2013-08-19 23:40:27 »

I would say that it is the other way around, there is more controversy about global state aka variables than having only a single instance of a class. On one hand using only a single instance of some class is a very common thing(webserver session data, thread pools ...). On the other having something mutable in global space(accessible from everywhere) is frowned upon.

So why shouldn't one just put stuff in the global space, it makes stuff so much easier right?
The thing is that global state is bad in many ways. Everywhere you use it in your code you get a hidden dependency to it. This will make debugging harder, can produce some nasty bugs(hard to find) and make it harder to split your app into modular parts.

The thing is with using global state, that it doesn't scale. If you really only plan to have only 1 or 2 global variables in a little app, it might be justifiable. On the other hand if your app is growing and your use of global state is growing also, at some point you will loose the oversight on things and adding or changing little things will get extremely difficult.

Which brings us back to the famous Singleton pattern, which should really be called Globalton pattern. This is because implementations use a global object to provide a single instance, which can have the same problems as above.

As a final note, don't do anything complicated stuff like your constructor thing or that getInstance method with null check. Just create your simple class which should be a Singleton any then create a final static instance of it somewhere else(NOT in the same class). This somewhere else could be the place where you store other constants for your game.
Offline relminator
« Reply #9 - Posted 2013-08-20 04:11:28 »

Thanks for all the quick responses. I'll look into the singleton pattern.

Out of curiosity do you use the singleton pattern for your primary class for your games?




Thanks,
Nathan

Yes.  Soundsystem, gamemanagers, everything that I need access globally. Though sometimes I use static.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline nsigma
« Reply #10 - Posted 2013-08-20 11:40:19 »

You'd want something like

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
public class A{
        private static A instance = null;
 
        private A() {       }
 
        public static synchronized A getInstance() {
                if (instance == null) {
                        instance = new A();
                }
                return instance;
        }
}

I am not 100% sure if it has to be synchronized? Someone more qualified can answer that

IMO there is almost never a point in doing lazy initialization of a singleton, unless you have lots of other static methods / fields in that class (in which case look at the inner class loading solution).  If the only static call you ever make is getInstance(), lazy initialization is pointless.  Using eager initialization ensures that the instance is created safely because class loading is thread safe, while meaning you don't have to synchronize every access to getInstance().

ie.
1  
2  
3  
4  
5  
6  
7  
8  
9  
public class A{
        private final static A INSTANCE = new A();
 
        private A() {       }
 
        public static A getInstance() {
                return INSTANCE;
        }
}


Singletons are over-used, but used sparingly they beat static methods.  Not only can you implement interfaces, but you could also make the class A above abstract.  That way you can easily swap in different implementations of A as required (testing, single / multi user, OS, etc.) - similar to what AWT's Toolkit.getDefaultToolkit() does.


Praxis LIVE - open-source intermedia toolkit and live interactive visual editor
Digital Prisoners - interactive spaces and projections
Offline sproingie

JGO Kernel


Medals: 202



« Reply #11 - Posted 2013-08-20 18:15:09 »

Quote
IMO there is almost never a point in doing lazy initialization of a singleton

... or for that matter, making them threadsafe.  That is, until you do need it, and spend hours tearing your hair screaming "Y U NO WORK?!"

Seriously, it's not hard to do it right.  Use Guice, use lazy initialization holders, use an Enum, all those get singletons right.  There's just no good reason to do it half-assed when you know it's going to bite you later.
 
Offline nsigma
« Reply #12 - Posted 2013-08-20 23:04:48 »

Seriously, it's not hard to do it right.  Use Guice, use lazy initialization holders, use an Enum, all those get singletons right.  There's just no good reason to do it half-assed when you know it's going to bite you later.

Trying to work out whether that was meant as criticizing what I wrote or agreeing with it?!   Undecided

The code I wrote is thread safe, the same way as the lazy initializer holder - which is what I meant by "inner class loading" if you really need lazy initialization.  Enum is also a good way to do it (still look weird to me) and deals with serialization - though if you're serializing your singletons I'd guess you've probably got bigger problems!  Grin

 

Praxis LIVE - open-source intermedia toolkit and live interactive visual editor
Digital Prisoners - interactive spaces and projections
Offline sproingie

JGO Kernel


Medals: 202



« Reply #13 - Posted 2013-08-21 07:31:25 »

Sorry, I read the wrong piece of code and attributed it to you.    Emo

Problem with a static initializer that isn't tucked away in an inner class is that you can't have dependencies on other singletons reliably since you can't guarantee that those have been initialized yet.  Of course it doesn't look very good even with the holder idiom, so once you have singletons that aren't leaves on the object graph, you start looking at DI containers, and there's an even deeper rabbit hole.   Tongue


Online Sickan

Senior Member


Medals: 9



« Reply #14 - Posted 2013-08-21 17:37:38 »

Uh, isn't the Java ClassLoader lazy? Shouldn't that mean that the instance variable is initialized when the class is first used - that is, the same behavior as writing the singleton accessor lazily? I'm fairly certain that the ClassLoader loads classes as they are needed by the program, so the dependencies of the singleton should be loaded when it's constructed - so at the same time that it is initialized.
Offline sproingie

JGO Kernel


Medals: 202



« Reply #15 - Posted 2013-08-21 17:51:52 »

The classloader may be lazy, but when the first use is in a static initializer, it effectively forces the whole graph, whereas inner classes are guaranteed initialized only on their first actual use within a method (though if you access it from a static initializer, you're in the same boat again).  Only likely to really bite you with circular dependencies, but those happen more often than you think if you're ever prone to create a global "context" object statically then have classes that also use it statically to connect to another singleton.  All in all it's another reason to avoid static global singletons in the first place.
Offline nsigma
« Reply #16 - Posted 2013-08-21 19:06:19 »

Uh, isn't the Java ClassLoader lazy? Shouldn't that mean that the instance variable is initialized when the class is first used - that is, the same behavior as writing the singleton accessor lazily?

That was exactly my point! Maybe I didn't word it well.  Lazy singleton initialization only has different semantics to eager initialization if you have other public static fields and/or methods that are accessed first.  I prefer the singleton being the only static and anything else being instance fields / methods - far less hassle and as you say the class loader itself is lazy and handles synchronization for you.

I get the feeling some people don't realise that the singleton isn't initialized until the class is actually used, so they go out of there way to create it lazily when they don't need to - point I was addressing in changing the above code.

Only likely to really bite you with circular dependencies, but those happen more often than you think if you're ever prone to create a global "context" object statically then have classes that also use it statically to connect to another singleton.

All the better to have the context object be the only singleton and all other objects be got from it wherever possible!

Praxis LIVE - open-source intermedia toolkit and live interactive visual editor
Digital Prisoners - interactive spaces and projections
Offline sproingie

JGO Kernel


Medals: 202



« Reply #17 - Posted 2013-08-21 20:00:18 »

All the better to have the context object be the only singleton and all other objects be got from it wherever possible!

At which point you're well on your way to reinventing your own DI container, and you should probably look at Guice or Dagger or PicoContainer.  Not that I'm religious about DI/IOC: I've got a few singletons sprinkled through my code that don't use any such thing, but they're straight up values, no collaboration going on.

Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

CogWheelz (14 views)
2014-08-01 22:53:16

CogWheelz (14 views)
2014-08-01 22:51:43

CopyableCougar4 (15 views)
2014-08-01 19:37:19

CogWheelz (19 views)
2014-07-30 21:08:39

Riven (27 views)
2014-07-29 18:09:19

Riven (16 views)
2014-07-29 18:08:52

Dwinin (14 views)
2014-07-29 10:59:34

E.R. Fleming (35 views)
2014-07-29 03:07:13

E.R. Fleming (13 views)
2014-07-29 03:06:25

pw (44 views)
2014-07-24 01:59:36
Resources for WIP games
by CogWheelz
2014-08-01 18:20:17

Resources for WIP games
by CogWheelz
2014-08-01 18:19:50

List of Learning Resources
by SilverTiger
2014-07-31 18:29:50

List of Learning Resources
by SilverTiger
2014-07-31 18:26:06

List of Learning Resources
by SilverTiger
2014-07-31 13:54:12

HotSpot Options
by dleskov
2014-07-08 03:59:08

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:58:24

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:47:22
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!