Singleton as global variables alternative

Download project ZIP

When it comes to design patterns it’s better to think twice before applying it. Let’s talk about the most controversial one – the “Singleton”.

Let’s imagine such a common situation: your project needs settings manager, event logger or language switcher.

If you are the beginner, the obvious way you are going to implement this is static classes usage. But it has a range of disadvantages:

  • Static class is not actually canonical class – it’s a namespace with functions and variables
  • Using static class is not a good practice because of breaking object-oriented programming principles
  • Static class cannot be passed as a parameter for other
  • Static class is not suitable for “lazy” initialization
  • Initialization and using of static class is always hard tracked
  • Multiple threads management is implemented hard

The task

Implement special Tracer class, designed to log the program behavior for further debugging. Messages log is saved in a text file. Note that Tracer must be accessible for entire project and has not to allow instantiating more than one object.

How to disable multiple instances?

In order to disable multiple instances singleton class must contain static instance field and private constructor (to prevent the instantiation outside):

How to access an instance?

For accessing the instance we have to implement the getter with a lazy initialization. It means that the singleton first initialization performs not on the program start, but on the first access attempt:

What if multiple threads will try to access instance at one time?

For preventing such unexpected behavior we may use locking instance in a critical section:

But locking an instance in a critical section every time program accessing it will reduce its performance seriously. It is better not to lock an instance, but other object to prevent instance access latencies:

In this case it is important to remember, that if object may be changed by multiple threads, using volatile specificator is mandatory.

Class functional

When implementing a functional, remember about threads concurrency and don’t forget to lock the resources:

Try it

To try our logger at multithreaded runtime, let’s write the following:

Program runs properly. Open the log – and you’ll see how multiple threads share single file:

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">