CSC/ECE 517 Fall 2010/ch3 3f sm: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
Line 1: Line 1:
==Introduction==
==Introduction==
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
 <br/>
: Ensures a class has only one instance, and provides a global point of access to it.  
==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.
The definiton can be explained as "we can have one and only one instance of the class." Singleton pattern is useful in cases where you need to interact with input and output devices,
;'''Singleton'''
to maintain thread pools , to log events in a single log file etc. Although the class diagram of the singleton class seems simple,
* Ensures a class has only one instance, and provides a global point of access to it.
It's 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 makes it so.
*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.
 <br/>
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.
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, subclassing etc. We will discuss the implementation of singleton pattern in dynamic and static languages below.
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.
 
 <br/><br />
 
'''Singleton Pattern in Java'''
==Singleton Pattern in Java==
 <br/><br />
Java is a statically typed object oriented language. Among other things this means that type checking is done in compile time 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.
 <br/><br />
<br/>
'''Implementation'''
'''Implementation'''
<br/> <br />
<br/>
Singleton pattern in java is implemented considering the 4 steps mention below.
:Singleton pattern in java is implemented considering the 4 steps mention below.
*Create a default constructor and make it private.
*Create a default constructor and make it private.
*Create a method for getting the reference to the singleton object.
*Create a method for getting the reference to the singleton object.
Line 27: Line 25:
* Prevent cloning of the object by overriding the object clone method.
* Prevent cloning of the object by overriding the object clone method.
<br/>
<br/>
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.
<pre>
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)
class SingletonObject {
<br/><br />
 
'''Synchronization'''
private static SingletonObject myObject;
<br /><br />
 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.
private SingletonObject() {
 <br/><br />
// Optional Code
'''Consequences of Synchronization'''
}
<br/><br />
public static SingletonObject getSingletonObject() {
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.
if (myObject == null) {
 <br/><br />
myObject = new SingletonObject();
'''Creating the clone'''
}
 <br/><br />
return myObject;
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)
}
 
}
 <br/>
</pre>
In this code we have followed the first two steps. 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 SingletonObject myObject = new SingletonObject(). To get the object of the singleton class
the developer must call the SingletonObject.instance() method. In the instance method a new object is being created if a singleton doesn’t exist, otherwise the existing
reference to SingletonObject is returned. This way the reference to same object is returned every time the instance method is called. In the above example we are using lazy
instantiation, that means the object is created only when the for the first time the initialize method is called. We could have also used early instantiation in that case
the object would be instantiated when the class is loaded.
<br/>
<pre>
class SingletonObject {
 
private static SingletonObject myObject;
 
private SingletonObject() {
// Optional Code
}
public static synchronized SingletonObjec myObject() {
if (myObject == null) {
myObject = new SingletonClass();
}
return myObject;
}
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
}
</pre>
'''Synchronization and Cloning'''
<br />
 The 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 can get 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 SingletonObject class. 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 closerlook at the code can tell us that
synchronizing access to the instance() method is not necessary after the object is created, that is after the first call to the initialize() method.  
 
We can still create a copy of the singleton by cloning it using the Object’s clone method.
It can be done like this SingletonObject clonedObject = (SingletonObject) obj.clone();.
To avoid this we have to override the clone method as shown above. We can just throw an exception when this method is called.
 
<br/>
==Singleton pattern in Ruby==
==Singleton pattern in Ruby==
<br/> 
<br/> 
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.
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.  


<code>
<pre>
require 'singleton'
class SingletonObject
class Logger
  include Singleton
 
   def initialize
   def initialize
    @log = File.open("log.txt", "a")
  #option code
   end
   end
    
    
   def log(msg)
  @@instance = SingletonObject.new
     @log.puts(msg)
 
   def self.instance
     return @@instance
   end
   end
 
  private_class_method :new
end
end
Logger.instance.log('message 2')
 
</code>
 
 
</pre>


 
 
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.
This is how singleton is implemented in ruby. In this case we are using static instantiation as you can see. We might have to use mutex and lock the block of code which runs initialize.
Its still a lot of things to care about, so ruby provides a simpler way to do it. Ruby standard library has a singleton module which we can use.
It defines the initialize method for us. It does lazy instantiation of the singleton object too.  
 
<pre>
require 'singleton'
 
class SingletonObject
  include Singleton
end
</pre>
 
include Singleton statement in the above code includes all the methods of the Singleton module. The instance method we saw in the previous example is implemented in the
Singleton module. This module uses the lazy instantiation method. 




==Conclusion==
==Conclusion==
 
Singleton pattern in both languages as seen above has to take care of a lot of implementation details. It is counter intuitive to the concept of objects and classes.
For example subclassing is another important thing to remember when we use the singleton pattern. We cannot subclass the singleton class as it may lead to duplication,
unecessary consequences in the lower classes etc.
Implementation of singleton pattern mostly decides on what tradeoff we are ready to make. If we dont call the initialize method too many times then we can make do with having
it being synchronized. If lazy instantiation is necessary then we have to tradeoff the convinience that comes with using static variables.
So now we have learned to implement the singleton pattern in static an dynamic variables.
 
 
 
 

Revision as of 01:52, 7 October 2010

Introduction

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.

The definiton can be explained as "we can have one and only one instance of the class." Singleton pattern 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, It's 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 makes it so. 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, subclassing etc. We will discuss the implementation of singleton pattern in dynamic and static languages below.


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.


class SingletonObject {

	private static SingletonObject myObject;
	
	private SingletonObject() {
		// Optional Code
	}
	public static SingletonObject getSingletonObject() {
		if (myObject == null) {
			myObject = new SingletonObject();
		}
		return myObject;
	}
}

In this code we have followed the first two steps. 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 SingletonObject myObject = new SingletonObject(). To get the object of the singleton class the developer must call the SingletonObject.instance() method. In the instance method a new object is being created if a singleton doesn’t exist, otherwise the existing reference to SingletonObject is returned. This way the reference to same object is returned every time the instance method is called. In the above example we are using lazy instantiation, that means the object is created only when the for the first time the initialize method is called. We could have also used early instantiation in that case the object would be instantiated when the class is loaded.

class SingletonObject {

	private static SingletonObject myObject;

	private SingletonObject() {
		//	 Optional Code
	}
	public static synchronized SingletonObjec myObject() {
		if (myObject == null) {
			myObject = new SingletonClass();
		}
		return myObject;
	}
	public Object clone() throws CloneNotSupportedException {
		throw new CloneNotSupportedException();
	}
}

Synchronization and Cloning
 The 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 can get 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 SingletonObject class. 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 closerlook at the code can tell us that synchronizing access to the instance() method is not necessary after the object is created, that is after the first call to the initialize() method.

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


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.

class SingletonObject
  def initialize
   #option code
  end
  
  @@instance = SingletonObject.new

  def self.instance
    return @@instance
  end
  
  private_class_method :new
end



  This is how singleton is implemented in ruby. In this case we are using static instantiation as you can see. We might have to use mutex and lock the block of code which runs initialize. Its still a lot of things to care about, so ruby provides a simpler way to do it. Ruby standard library has a singleton module which we can use. It defines the initialize method for us. It does lazy instantiation of the singleton object too.

require 'singleton'

class SingletonObject
  include Singleton
end

include Singleton statement in the above code includes all the methods of the Singleton module. The instance method we saw in the previous example is implemented in the Singleton module. This module uses the lazy instantiation method.


Conclusion

Singleton pattern in both languages as seen above has to take care of a lot of implementation details. It is counter intuitive to the concept of objects and classes. For example subclassing is another important thing to remember when we use the singleton pattern. We cannot subclass the singleton class as it may lead to duplication, unecessary consequences in the lower classes etc. Implementation of singleton pattern mostly decides on what tradeoff we are ready to make. If we dont call the initialize method too many times then we can make do with having it being synchronized. If lazy instantiation is necessary then we have to tradeoff the convinience that comes with using static variables. So now we have learned to implement the singleton pattern in static an dynamic variables.        

References