next up previous contents
Next: Dynamic Starter Pattern: Runtime Up: Patterns Previous: Patterns   Contents

Singleton Pattern: One Global Object [52]



$\bullet$ Problem: How to create just one instance of a globally-accessible object?

$\bullet$ Solution: Singleton Pattern

$\bullet$ Outline: Instead of making all attributes and methods static, make just one static attribute (instance), whose type is the globally-accessible object, along with a static method, which returns this instance.




Original Code:

public class AudioClipManager {
  private AudioClip prevClip;
  public AudioClipManager() {}
  public play(:AudioClip) {}
  public loop(:AudioClip) {}
  public stop() {}
}

AudioClipManager acm = new AudioClipManager();
acm.play(audioClip);
acm.loop(audioClip);
acm.stop();

Awkward conversion to all statics:

public class AudioClipManager {
  private static AudioClip prevClip;
  // no constructor
  public static play(:AudioClip) {}
  public static loop(:AudioClip) {}
  public static stop() {}
}

AudioClipManager.play(audioClip);
AudioClipManager.loop(audioClip);
AudioClipManager.stop();



Singleton Pattern: One Global Object [53]




\begin{picture}(460,180)(35,620)\thicklines
\put( 35,620){\framebox (205,180)...
...80){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm Singleton}}}
\end{picture}




public class AudioClipManager {
  // singleton constructs itself when class loader detects first reference 
  private static AudioClipManager instance = new AudioClipManager();

  // normal instance data
  private AudioClip prevClip;

  // private constructor since singleton constructs itself
  // do not want a default public constructor from the compiler
  private AudioClipManager() {}

  public static AudioClipManager getInstance() {
    return instance;
  }

  // normal instance methods
  public play(:AudioClip) {}
  public loop(:AudioClip) {}
  public stop() {}
}

// one static call to get the instance
// first such call triggers class loading and construction of singleton
AudioClipManager acm = AudioClipManager.getInstance();

// the rest are just normal instance calls
acm.play(audioClip);
acm.loop(audioClip);
acm.stop();



Ted Billard 2006-09-26