Skip to main content
GameDev.net gamedev.net
🔒 Locked

[java] Call-back, static methods or singletons?

Started by Addictman Jun 29, 2004 at 4:11 AM 5 replies 750+ views
Original Post
Addictman
Addictman
Without doubt, you've all been there. You got your nice heap of classes, and now you encounter the "problem" where some classes need to talk to some classes you initially didnt think needed to communicate. Which solution do you use, and why? I am often in argument with myself in choosing the solutions here. There are pros and cons with both using Call-back (sending objects that communicate through for instance constructors), using static methods, and using singleton classes. Thoughts? Static methods pose a slight delay, so does argument passing with objects, and singleton classes naturally restrict themselves to one instance of the class.
Development blog, The Omega Sector -- http://www.omegasector.org
SiCrane
SiCrane
I don't think there are any one size fits all solution to this kind of situation. Any reasonable advice would depend on knowing more details about our particular problem. For example I could say that in general singletons are over used, but it might turn out that a singleton is exactly what you need. (But, in general, singletons are overused. :) )
Addictman
Addictman
No, you're right, there is definitely not a one solution fits all answer. But I bet you have some general rules as to when you see the different solutions as suitable :) Share your thoughts. I usually use Singletons for the large back-bone classes that form the center of the spiderweb of class communication. Not only do I only want one instance of these, but creating several instances could have .. unfortunate effects.

I usually use static methods when few classes need to communicate, who in their construction, have nothing to do with each other. Or of course when I want to execute "pure code" that has nothing to do with the instances of the class at all.

And I usually use call-back when related to GUI components (typically those delivered by Sun), and in scenarios where the communication is very frequent inbweteen the classes.


This is nothing that's been taught to me, so you may freely disagree with me, or point out things I am missing ;)
Development blog, The Omega Sector -- http://www.omegasector.org
nonnus29
nonnus29
Quote:
There are pros and cons with both using Call-back (sending objects that communicate through for instance constructors),


I'm not familiar with this. How about an example?
Addictman
Addictman
I'd be more than happy to give an example.


Suppose you want to implement a Timer class. You want to be able to program your class to:

- Start the timer,
- have the timer measure some time delay,
- then carry out some action when the correct time has elapsed.


For this to be practical, the Timer class needs a way of communicating with the calling class. This is usually called a callback method. Interfaces are the preferred way to implement callback methods in Java.

Look at the Timer class here.

class Timer extends Thread
{
.......
public void run()
{
while(true)
{
sleep(delay);
// now what?
}
}
}

The object constructing the Timer object must somehow tell the timer what to do when the time is up. We will use an interface here, whereas in C++, you would use function pointers.
So the // now what? comment in the preceding code is replaced by a method call that was declared inside an interface.
Thus, in addition to the Timer class, we need an interface called
TimerListener. It has a single method called timeElapsed.

interface TimerListener
{
public void timeElapsed(Timer t);
}

Any class wanting to be called from a timer must implement that interface. The constructor of the Timer object is given a reference to an object that implements the TimerListener interface. That object is notified, via its timeElapsed method, whenever the time has progressed to the next interval.

In the following example, an AlarmClock class both constructs a Timer object and implements the TimerListener interface. In the constructor of the Timer object, it passes the this reference, a reference to itself, to be notified at every timer tick. The timeElapsed method simply checks whether it is time to play the blingBling audio clip.

class AlarmClock implements TimerListener
{
AlarmClock()
{
Timer t = new Timer(this);
t.setDelay(1000); // 1000 ms
}

public void timeElapsed(Timer t)
{
if(t.getTime() >= blingBlingTime)
blingBling.wakeTheFool();
}
}

Below is the code for the Timer class. Notice how the constructor of the Timer class receives the reference to the object that needs to be notified and stores it in the listener variable. Whenever the timing interval has elapsed, its timeElapsed() method is called. Because the listener object implements the TimerListener interface, the compiler knows that it supports a timeElapsed method.

class Timer extends Thread
{
TimeListener listener = null;

Timer(TimerListener t)
{
listener = t;
}

......

public void run()
{
while(true)
{
sleep(interval);
// Here is the magic
listener.timeElapsed(this);
}
}
}


There you go. I hope that the explanation was helpful. If not, just ask more, and I'll try to elaborate.


Development blog, The Omega Sector -- http://www.omegasector.org
capn_midnight
capn_midnight
I don't have time to read through all the posts right now (got a photo shoot to take care of) but I really suggest checking out the Observable/Observer interface and class. It's really quite a simple concept, one could practically rewrite it in a day, but it works out quite well. I used it to great extent on a recent project involving tracking stock prices and groups of stocks.
nonnus29
nonnus29
That's a good explanation Addictman, thanks.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.