CSC/ECE 517 Fall 2007/wiki1b 6 c1: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
 
(36 intermediate revisions by 2 users not shown)
Line 5: Line 5:


== <b>Singleton Pattern</b> ==
== <b>Singleton Pattern</b> ==
The Singleton pattern is a design pattern used to insure the existence of a single instance of a class in the run time. It constructs the object once and returns a reference to this object every time thereafter. In a multithreading environment, special care should be taken.
The Singleton Pattern is a design pattern used to insure the existence of a single instance of a class in the run time. It constructs the object once and returns a reference to this object every time thereafter. In a multithreading environment, special care should be taken.


===<b>Global Variables versus Singleton</b>===
===<b>Global Variables versus Singleton</b>===
Singletons are often mistaken as global variables.  These two are very similar but the main difference between the two is that the Singleton Pattern deals with how to limit instances, while global variables deal with how programmers declare instances.  Singletons are frequently mistaken by programmers that are inexperienced because they usually think that the use of Singleton Pattern will solve problems that are associated with global variables.
Singletons are often mistaken as global variables.  These two are very similar but the main difference between the two is that the Singleton Pattern deals with how to limit instances, while global variables deal with how programmers declare instances.  When programming, one should not think that the use of Singleton Pattern would solve problems that are associated with global variables because this is a common mistake.


===<b>Benefits of Singleton Pattern</b>===
===<b>Benefits of Singleton Pattern</b>===
There benefits of using the singleton pattern over other patterns and global variables.  When using Singleton Pattern it allows instance control by preventing other objects from instantiating their own copies of the Singleton object which would ensure that all objects access the single instance.  Using the Singleton Pattern also gives a little flexibility since the class controls the instantiation process and has the flexibility to change the instantiation process. Singleton Pattern allows reduced name space because the Singleton class can be subclassed,which makes it easier to configure an application with an instance of this extended class. The application can be configures with an instance of the class one needs at run-time. <br> <br>  
There are benefits of using the singleton pattern over other patterns and global variables.  When using Singleton Pattern it allows instance control by preventing other objects from instantiating their own copies of the Singleton object which would ensure that all objects access the single instance.  Using the Singleton Pattern also gives a little flexibility since the class controls the instantiation process and has the flexibility to change the instantiation process. Singleton Pattern allows reduced name space because the Singleton class can be subclassed,which makes it easier to configure an application with an instance of this extended class. The application can be configures with an instance of the class one needs at run-time. <br><br>
Several uses appear to Singleton Pattern which include; logger (which is our example here), payment form, applcation preference, many dialogs in the GUI environemt, ... etc.
Several uses of Singleton Pattern include logger (which is our example), payment form, application preference, many dialogs in GUI environemt, and etc.
 
==<b>Class Diagram</b>==
[[Image:singleton.png]]


== <b>Implementation</b> ==
== <b>Implementation</b> ==
The Singleton pattern is implemented by <br>
To implement Singleton do following steps<br>
- Creating a class with a method which will create a new instance of the class (If one doesn't already exist)<br>
1- Turn your class constructor to private<br>
- The constructor of this class is turned to private or protected<br>
2- Create a public method -getInstance()- to return a refrence to the instance. If the object is not initialized yet (object == null) it will create one by invoking the constructor.<br>
- Another public function is used to call this constructor.<br>
3- In multithreading environment, synchoranize your getInstance() method so you don't end with Doubleton or Tripleton.<br>
- If the object is not initialized yet (object == null) it calls the constructor and returns a reference else it will just return a reference.<br>
4- Consider overiding the clone method in Java, so no one can copy your Singleton.<br>  


In multithreading environment, a synchronized command should be used so not every thread in the program can initialize its own instance of the singleton class.
In multithreading environment, a synchronized command should be used so not every thread in the program can initialize its own instance of the singleton class.




==<b>Class Diagram</b>==
=== <b>Example Implementations</b> ===
[[Image:singleton.png]]
 
 
== <b>Example Implementations</b> ==
To demonstrate further let us consider programs that implement a logger in Java and then in Ruby.  
To demonstrate further let us consider programs that implement a logger in Java and then in Ruby.  


===<b>Java</b>===
====<b>Java</b>====




Line 39: Line 38:
       // Exists only to defeat instantiation.
       // Exists only to defeat instantiation.
   }
   }
   public static LoggerSingleton getInstance() {
   public static synchronized LoggerSingleton getInstance() {
       if(instance == null) {
       if(instance == null) {
         instance = new LoggerSingleton();
         instance = new LoggerSingleton();
       }
       }
       return instance;
       return instance;
  }
  public Object clone() throws CloneNotSupportedException {
    throw new CloneNotSupportedException();
   }
   }
   // add other attributes
   // add other attributes
Line 49: Line 51:




<b>or you might consider next more simple implementation in Java,</b><br>


===<b>Ruby</b>===  
 
public class LoggerSingleton {
  private final static LoggerSingleton instance = new Singleton();
  private LoggerSingleton () {
  }
  public static LoggerSingleton getInstance() {
    return instance ;
  }
}
 
====<b>Ruby</b>====
 
or for sure the super simple coding in Ruby,




Line 56: Line 73:
  class LoggerSingleton
  class LoggerSingleton
   include Singleton  
   include Singleton  
  end  
  end
 
===<b>Invoking Singletons</b>===
 
The following coding is to invoke a singleton class in Java then in Ruby
 
====<b>Java</b>====
 
 
LoggerSingleton logger1 = LoggerSingleton.getInstance();
LoggerSingleton logger2 = LoggerSingleton.getInstance();
LoggerSingleton logger3 = new LoggerSingleton(); // compilation error will occur; The constructor is private.
System.out.println(logger1);
System.out.println(logger2);
 
====<b>Ruby</b>====
 
logger1 = LoggerSingleton.instance
logger2 = LoggerSingleton.instance




==<b>Test Singletons</b>==


The following coding is to test singleton class 
===<b>Test Singletons</b>===


===<b>Java</b>===
The following coding is to test singleton class in Java then in Ruby
 
====<b>Java</b>====




Line 84: Line 120:
     }
     }


===<b>Ruby</b>===
====<b>Ruby</b>====


  def test_singleton
  def testSingleton
  class << OnlyOne.instance
    logger1 = LoggerSingleton.instance  
     def reset
     logger2 = LoggerSingleton.instance  
      # reset state
    assertEqual logger1, logger2
    end
  end
  OnlyOne.instance.modify_state
  OnlyOne.instance.reset
  end
  end




== <b>Comparison</b> ==
When comparing Singleton Pattern in Java and Ruby, it is shown that Ruby obviously is better than Java in terms of clarity and succinctness. It seems that Ruby would win because of the simplicity compared to Java since only one line of code "include Singleton" enables all the functionalities when Java needs more lines to do this.  Moreover Ruby Singleton mixin work safe in multithreading environment.
Since Ruby is a dynamic language that uses singleton mixins, it is easier to implemenet and since Java does not use mixins, it requires  more implementation in the coding.


== <b>Conclusion</b> ==
== <b>Conclusion</b> ==
Java doesn’t contain singleton pattern in the language itself, although implementation for the pattern is still possible. While in Ruby the singleton pattern is in the language itself, which became possible since Ruby is a dynamic language through singleton module.
Singleton is a very popular design pattern, and mostly the most popular. While Java doesn’t support Singleton pattern through the language itself, Ruby provide one line code to make your class a singleton (which is compatable with multithreading and Unit testing environments). Although implementation become more clear and easier in Ruby, you still have to use your Singleton wisely.
 
== <b>References</b> ==
[http://www.oreilly.com/catalog/hfdesignpat/ Head First Design Patterns]<br>
[http://www.oreilly.com/catalog/0974514055/ Programming Ruby: The Pragmatic Programmers' Guide] <br>
[http://java.sun.com/docs/books/effective/ Effective Java Programming Language Guide] <br>
[http://en.wikipedia.org/wiki/Singleton_pattern Singleton Pattern Wiki] <br>
[http://www.beginner-java-tutorial.com/singleton.html Simple Implementation in Java] <br>
[http://www.oodesign.com/oo_design_patterns/creational_patterns/singleton.html Singleton examples] <br>
 
== <b>External Links</b> ==
[http://c2.com/cgi/wiki?SingletonPattern Singleton Article] <br>
[http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/18751 Bug in Ruby Singleton Class] <br>
[http://steve.yegge.googlepages.com/singleton-considered-stupid Singleton Considered Stupid!] <br>
[http://www.ibm.com/developerworks/library/co-single.html Use Your Singleton Wisely] <br>
[http://michaelfeathers.typepad.com/michael_feathers_blog/2006/10/singleton_is_in.html Singleton is Incompatable with Unit Testing] <br>

Latest revision as of 03:32, 11 October 2007

Take a case of the Singleton pattern and implement it as succinctly as possible in Ruby and Java. Compare the two implementations in terms of clarity and succinctness. The example should be a "real-world" example. While it may be grossly oversimplified for the purpose of illustration, it should not be totally contrived.


Singleton Pattern

The Singleton Pattern is a design pattern used to insure the existence of a single instance of a class in the run time. It constructs the object once and returns a reference to this object every time thereafter. In a multithreading environment, special care should be taken.

Global Variables versus Singleton

Singletons are often mistaken as global variables. These two are very similar but the main difference between the two is that the Singleton Pattern deals with how to limit instances, while global variables deal with how programmers declare instances. When programming, one should not think that the use of Singleton Pattern would solve problems that are associated with global variables because this is a common mistake.

Benefits of Singleton Pattern

There are benefits of using the singleton pattern over other patterns and global variables. When using Singleton Pattern it allows instance control by preventing other objects from instantiating their own copies of the Singleton object which would ensure that all objects access the single instance. Using the Singleton Pattern also gives a little flexibility since the class controls the instantiation process and has the flexibility to change the instantiation process. Singleton Pattern allows reduced name space because the Singleton class can be subclassed,which makes it easier to configure an application with an instance of this extended class. The application can be configures with an instance of the class one needs at run-time.

Several uses of Singleton Pattern include logger (which is our example), payment form, application preference, many dialogs in GUI environemt, and etc.

Class Diagram

Implementation

To implement Singleton do following steps
1- Turn your class constructor to private
2- Create a public method -getInstance()- to return a refrence to the instance. If the object is not initialized yet (object == null) it will create one by invoking the constructor.
3- In multithreading environment, synchoranize your getInstance() method so you don't end with Doubleton or Tripleton.
4- Consider overiding the clone method in Java, so no one can copy your Singleton.

In multithreading environment, a synchronized command should be used so not every thread in the program can initialize its own instance of the singleton class.


Example Implementations

To demonstrate further let us consider programs that implement a logger in Java and then in Ruby.

Java

public class LoggerSingleton {
  private static LoggerSingleton instance = null;
  private LoggerSingleton() {
     // Exists only to defeat instantiation.
  }
  public static synchronized LoggerSingleton getInstance() {
     if(instance == null) {
        instance = new LoggerSingleton();
     }
     return instance;
  }
  public Object clone() throws CloneNotSupportedException {
   	throw new CloneNotSupportedException(); 
  }
  // add other attributes
}


or you might consider next more simple implementation in Java,


public class LoggerSingleton {
  private final static LoggerSingleton instance = new Singleton();

  private LoggerSingleton () {
  }

  public static LoggerSingleton getInstance() {
    return instance ;
  }
}

Ruby

or for sure the super simple coding in Ruby,


require 'singleton' 
class LoggerSingleton
  include Singleton 
end

Invoking Singletons

The following coding is to invoke a singleton class in Java then in Ruby

Java

LoggerSingleton logger1 = LoggerSingleton.getInstance();	
LoggerSingleton logger2 = LoggerSingleton.getInstance();
LoggerSingleton logger3 = new LoggerSingleton(); // compilation error will occur; The constructor is private.
System.out.println(logger1);
System.out.println(logger2);

Ruby

logger1 = LoggerSingleton.instance 
logger2 = LoggerSingleton.instance 


Test Singletons

The following coding is to test singleton class in Java then in Ruby

Java

import junit.framework.Assert; 
import junit.framework.TestCase; 
public class TestSingleton extends TestCase {
 private LoggerSingleton logger1 = null, logger2 = null;
 public TestSingleton(String name) {
   super(name);
 }
 public void setUp() {
       logger1 = LoggerSingleton.getInstance();
       logger2 = LoggerSingleton.getInstance();
  }
 public void testUnique() {
       System.out.println(logger1);
       System.out.println(logger2);
       Assert.assertEquals(true, logger1 == logger2);
      }
   }

Ruby

def testSingleton
   logger1 = LoggerSingleton.instance 
   logger2 = LoggerSingleton.instance 
   assertEqual logger1, logger2
end


Comparison

When comparing Singleton Pattern in Java and Ruby, it is shown that Ruby obviously is better than Java in terms of clarity and succinctness. It seems that Ruby would win because of the simplicity compared to Java since only one line of code "include Singleton" enables all the functionalities when Java needs more lines to do this. Moreover Ruby Singleton mixin work safe in multithreading environment.

Since Ruby is a dynamic language that uses singleton mixins, it is easier to implemenet and since Java does not use mixins, it requires more implementation in the coding.

Conclusion

Singleton is a very popular design pattern, and mostly the most popular. While Java doesn’t support Singleton pattern through the language itself, Ruby provide one line code to make your class a singleton (which is compatable with multithreading and Unit testing environments). Although implementation become more clear and easier in Ruby, you still have to use your Singleton wisely.

References

Head First Design Patterns
Programming Ruby: The Pragmatic Programmers' Guide
Effective Java Programming Language Guide
Singleton Pattern Wiki
Simple Implementation in Java
Singleton examples

External Links

Singleton Article
Bug in Ruby Singleton Class
Singleton Considered Stupid!
Use Your Singleton Wisely
Singleton is Incompatable with Unit Testing