CSC/ECE 517 Fall 2007/wiki1b 6 aa
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 (i.e., should not raise the question, Why would anyone ever want to do that?).
Comparison
Ruby can implement singleton pattern by simply referencing the singleton module and all its methods will be included. The singleton mixin makes the constructor inaccessible, override clone and dup methods, and take care of all the threading complications.
Java has no mixins, so singleton implementation in Java has to do the following:
- block off access to constructor by making it private
- provide a static method for getting an instance of the singleton,
- prevent cloning by overriding the clone() method explicitly
- ensure thread safety
Real World Example
Let's take the example of the Earth. Because we only have one earth,it is appropriate to implement the Earth class in singleton.In side the class, currentCondition describes the state (current condition) of the earth.
Ruby Implementation
require 'Singleton' class Earth include Singleton # include singleton mixin attr_accessor :currentCondition end
Java Implementation
public class Earth { private Earth() { // override the contructor to make it private } private static Earth ref; // make the method thread safe public synchronized static Earth getEarth() { if (ref == null) synchronized (Earth.class) { // for thread-safety if (ref == null) ref = new Earth ( ); } return ref; } public Object clone() throws CloneNotSupportedException { throw new CloneNotSupportedException(); } private String currentCondition="I was beautiful and clean"; public String getCurrentCondition(){ return currentCondition; } public void setCurrentCondition(String str){ currentCondition=str; } }
Test
Ruby Test code
class People def pollute(a) # pollute an earth object a.currentCondition="i am old and polluted" end def test p=People.new earth1=Earth.instance earth2=Earth.instance earth1.currentCondition="I am young and clean" puts "Earth1 says: " + earth1.currentCondition puts "Earth2 says: " + earth2.currentCondition # pollute earth1 p.pollute(earth1) puts "After people pollute earth1" puts "Earth1 says: " + earth1.currentCondition puts "Earth2 says: " + earth2.currentCondition end end p=People.new p.test
Java test code
public class People { public void pollute(Earth earth){ earth.getEarth().setCurrentCondition("I am dirty and polluted"); } public static void main(String args[]){ People p=new People(); Earth earth1= Earth.getEarth(); Earth earth2= Earth.getEarth(); System.out.println("earth1 says: " +earth1.getCurrentCondition()); System.out.println("earth2 says: " +earth2.getCurrentCondition()); p.pollute(earth1); System.out.println("After people pollute earth1"); System.out.println("earth1 says: " +earth1.getCurrentCondition()); System.out.println("earth2 says: " +earth2.getCurrentCondition()); } }
Test Result
Both the java code and the ruby code will produce the following output
earth1 says: I was beautiful and clean earth2 says: I was beautiful and clean After people pollute earth1 earth1 says: I am dirty and polluted earth2 says: I am dirty and polluted
References
Books
Links
- - Ruby standard library documentation
- Design Patterns - Wikipedia
- - Patterns in Ruby: Singleton Pattern
See Also
- []