CSC/ECE 517 Fall 2010/ch3 3f sm

From Expertiza_Wiki
Revision as of 01:29, 7 October 2010 by Smkakara (talk | contribs)
Jump to navigation Jump to search

Introduction

     

Singleton

Singleton pattern has the simplest class diagram among all the design patterns discussed by the gang of four. It has just one class. It has some interesting characteristics. Lets start with the definition itself.
Singleton
  • Ensures a class has only one instance, and provides a global point of access to it.
  • It means that we can have one and only one instance of the class.
  •  This is useful in cases where you need to interact with input and output devices, to maintain thread pools, to log events in a single log file etc. Although the class diagram of the singleton class seems simple, Its implementation can be quite a task.
  • To make sure its peculiar behavior of having just one object and serving up the same object when requested is non trivial.

 
Classes are naturally designed in a way that we create many instances of them. So we have to move against this and make sure we have only one object.   We have to take care of multi threading scenarios, sub classing etc.  We will discuss the implementation of singleton pattern in dynamic and static languages and then compare and contrast the two.  

Singleton Pattern in Java  

Java is a statically typed object oriented language. Among other things this means that type checking is done in compile time in java.  

Implementation
 
Singleton pattern in java is implemented considering the 4 steps mention below.

  • Create a default constructor and make it private.
  • Create a method for getting the reference to the singleton object.
  • Make the access method synchronized to prevent thread issues.
  • Prevent cloning of the object by overriding the object clone method.


In this step we are making the default constructor private. This means that the constructor can be accessed only by other methods inside the class. This prevents a developer from creating an object of the class by using the myObject name = new myObject() method.  To get the object of the singleton class the developer must call the myObject.instance() method. In the instance method a new object is being created if a singleton doesn’t exist, otherwise the existing singleton is returned. This way the reference to same object is returned every time instance is called. (lazy initialization)

Synchronization

 Above code seems to be good enough for a singleton pattern, but when we take a closer look we realize that when multiple threads access this instance method, there is a possibility that more than one object gets created. So we need to make this method synchronized. This makes sure that only one thread can access this function at a time and thus ensuring that only object is ever created of the singleton class.  

Consequences of Synchronization

Synchronizing the singleton method has some consequences. This may result in performance loss if the singleton instance method is being accessed a lot of times in our over all application.This may be the case in some singletons which manage i/o operations, write logs to the same file etc.  A closer look at the code can tell you that synchronizing access to the instance() method is not necessary after the object is created.  

Creating the clone  

We can still create a copy of the singleton by cloning it using the Object’s clone method. This can be done as shown SingletonObject clonedObject = (SingletonObject) obj.clone();.To avoid this we have to override the clone method as well. We can just throw an exception when this method is called. (sub classing)    

Singleton pattern in Ruby


  Ruby is a dynamically typed object oriented language. This means type checking happens at run time. Implementing the singleton pattern in ruby has the same aspects as in java. So we can just write the ruby equivalent of the code above and we have the ruby singleton pattern. Just to show how it looks we have it down here.

require 'singleton' class Logger

 include Singleton
 
 def initialize
   @log = File.open("log.txt", "a")
 end
 
 def log(msg)
   @log.puts(msg)
 end

end Logger.instance.log('message 2')

  This looks pretty complex so ruby provides a simpler way to do it. Ruby standard library has a singleton module that we can use. It defines the initialize method for me. It does lazy instantiation of the singleton object too.


Conclusion

         

References