CSC/ECE 517 Fall 2009/wiki2 13 ncs: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
Line 7: Line 7:
* Are there instances where a design pattern should be used in a dynamic language than a static language  
* Are there instances where a design pattern should be used in a dynamic language than a static language  


=Design Patterns Analysis=
=Design Patterns in JAVA vs Ruby=


==Singleton Pattern==
==Singleton Pattern==
Line 20: Line 20:
* implement a getInstance method and make the it thread safe.  
* implement a getInstance method and make the it thread safe.  


<todo> JAVA and ruby singletone examples here. </todo>


However in JAVA we would need to redo these steps for all classes that we want to be singleton whereas in Ruby we can simply include the singleton module that automatically gets us the functionality listed above.  
However in JAVA we would need to redo these steps for all classes that we want to be singleton whereas in Ruby we can simply include the singleton module that automatically gets us the functionality listed above.  
Line 29: Line 28:
In JAVA we typically do something like  
In JAVA we typically do something like  


<source lang="java">
<code>


interface IObjectFactory {
  interface IObjectFactory {
    IGear createObject();
  }


IGear createObject();
  class ConcreteObjectFactory implements IObjectFactory{
  IObject createObject() {
    if ( some condition )
        return new XObject();
    else
        return new YObject();
  }


}
  class ObjectUser {
    public void doSomething(IObjectFactory factory ) {
        IObject my_Object = factory.createObject();
    }
  }
</code>


class ConcreteObjectFactory implements IObjectFactory{
We can technically do the exact same thing in Ruby however Ruby being a dynamic language there are no special classes or class methods in ruby. Ruby allows us to rename our factory method to be called new.


IObject createObject() {
<code>
  class ObjectFactory


if ( some condition )
    def new()
      if ( ... some condition )
        return XObject.new()
      else
        return YObject().new()
    end


return new XObject();
  end


else
<source>
 
return new YObject();
 
}
 
class ObjectUser {
 
public void doSomething(IObjectFactory factory ) {
 
 
IObject my_Object = factory.createObject();
 
}
 
}
</source>
We can technically do the exact same thing in Ruby however Ruby being a dynamic language there are no special classes or class methods in ruby. Ruby allows us to rename our factory method to be called new
 
<source lang="Ruby">
class ObjectFactory


def new()
if ( ... some condition )
return XObject.new()
else
return YObject().new()
end
end
end
<source>
Our client class now becomes:
Our client class now becomes:


<source lang="Ruby">
<code>
class ObjectUser


def doSomething(factory )
  class ObjectUser
    def doSomething(factory )
      ...
      my_object = factory.new()
      ...
    end
  end


...
</code>


my_object = factory.new()
==Iterators==
 
Iterators are design patterns used to access the elements of an aggregate object sequentially without exposing its underlying representation. To use iterators we need  
...
 
end
 
end
<source>
 
=Iterators= Iterators are design patterns used to access the elements of an aggregate object sequentially without exposing its underlying representation. To use iterators we need  


* An iterator declared and initialized to point to the collection  
* An iterator declared and initialized to point to the collection  
Line 108: Line 87:


In JAVA we will need to know the type of objects in the collection whereas in ruby iterators are built right in. here are some examples that show the ease with which we can use iterators in Ruby  
In JAVA we will need to know the type of objects in the collection whereas in ruby iterators are built right in. here are some examples that show the ease with which we can use iterators in Ruby  
<code>
  a = [ 10, 20, 30, 40 ]
  a.each { |element| print "The element is #{element}\n" }


a = [ 10, 20, 30, 40 ]
  Thread.list.each { |t| print "Thread: #{t}\n" }
 
a.each { |element| print "The element is #{element}\n" }
 
 
Thread.list.each { |t| print "Thread: #{t}\n" }
 
ObjectSpace.each_object { |o| print "Object: #{o}\n" }


open("data.txt").each_line { |line| print "The line is #{line}\n" }
  ObjectSpace.each_object { |o| print "Object: #{o}\n" }


<TODO> Some more patterns
  open("data.txt").each_line { |line| print "The line is #{line}\n" }


</code>
=Conclusion=
=Conclusion=


Design patterns are concepts that are equally applicable to solve problems regardless of the language we use to implement the solution. So I cannot think of a case where a specific apttern will be more useful or pertinent to be used in a dynamic language than a static language. However given the features of dynamic languages like Ruby that support metaprogramming and reflection via Modules and Mixins and support extending/reopening classes and redfining methods at run time definitely make it easier to implement patterns with less lines of code. Ruby lets us hide the details of implementations of design patterns much more effectively. You can make a class a singleton with a simple "include Singleton". You can make factories that look exactly like ordinary classes. You can define visitors with a couple of curly braces. All of this allows you to compress out the details and simply say more interesting things in each line of code.
Design patterns are concepts that are equally applicable to solve problems regardless of the language we use to implement the solution. So I cannot think of a case where a specific apttern will be more useful or pertinent to be used in a dynamic language than a static language. However given the features of dynamic languages like Ruby that support metaprogramming and reflection via Modules and Mixins and support extending/reopening classes and redfining methods at run time definitely make it easier to implement patterns with less lines of code. Ruby lets us hide the details of implementations of design patterns much more effectively. You can make a class a singleton with a simple "include Singleton". You can make factories that look exactly like ordinary classes. You can define visitors with a couple of curly braces. All of this allows you to compress out the details and simply say more interesting things in each line of code.

Revision as of 23:55, 8 October 2009

Introduction

Ruby allows much more concise implementations of design patterns for example a single line of code is enough to implement the singleton pattern. We will look at some design patterns and compare the implementation in Ruby vs Java with the goal to determine the following

  • can dynamic typed languages realize the design patterns more effectively than statically typed languages
  • Are there instances where a design pattern should be used in a dynamic language than a static language

Design Patterns in JAVA vs Ruby

Singleton Pattern

Resticting the instantiation of the class to a single pattern.

The implementation of the pattern in JAV And Ruby is identical. We need to

  • make the constructor private
  • declare a instance variable
  • implement a getInstance method and make the it thread safe.


However in JAVA we would need to redo these steps for all classes that we want to be singleton whereas in Ruby we can simply include the singleton module that automatically gets us the functionality listed above.

Factory Pattern

Isolate the code to create an object from the concrete implementation of the class.

In JAVA we typically do something like

 interface IObjectFactory {
    IGear createObject();
 }
 class ConcreteObjectFactory implements IObjectFactory{
 IObject createObject() {
    if ( some condition )
       return new XObject();
    else
       return new YObject();
 }
 class ObjectUser {
    public void doSomething(IObjectFactory factory ) {
       IObject my_Object = factory.createObject();
    }
 }

We can technically do the exact same thing in Ruby however Ruby being a dynamic language there are no special classes or class methods in ruby. Ruby allows us to rename our factory method to be called new.

 class ObjectFactory
   def new() 
     if ( ... some condition )
        return XObject.new()
     else
        return YObject().new()
   end
 end

<source>

Our client class now becomes:

 class ObjectUser 
   def doSomething(factory )
     ...
     my_object = factory.new()
     ...
   end
 end

Iterators

Iterators are design patterns used to access the elements of an aggregate object sequentially without exposing its underlying representation. To use iterators we need

  • An iterator declared and initialized to point to the collection
  • Write a loop and use the iterator to get the value of the next sequential objec tin the collection.

In JAVA we will need to know the type of objects in the collection whereas in ruby iterators are built right in. here are some examples that show the ease with which we can use iterators in Ruby

 a = [ 10, 20, 30, 40 ]
 a.each { |element| print "The element is #{element}\n" }
 Thread.list.each { |t| print "Thread: #{t}\n" }
 ObjectSpace.each_object { |o| print "Object: #{o}\n" }
 open("data.txt").each_line { |line| print "The line is #{line}\n" }

Conclusion

Design patterns are concepts that are equally applicable to solve problems regardless of the language we use to implement the solution. So I cannot think of a case where a specific apttern will be more useful or pertinent to be used in a dynamic language than a static language. However given the features of dynamic languages like Ruby that support metaprogramming and reflection via Modules and Mixins and support extending/reopening classes and redfining methods at run time definitely make it easier to implement patterns with less lines of code. Ruby lets us hide the details of implementations of design patterns much more effectively. You can make a class a singleton with a simple "include Singleton". You can make factories that look exactly like ordinary classes. You can define visitors with a couple of curly braces. All of this allows you to compress out the details and simply say more interesting things in each line of code.