CSC/ECE 517 Fall 2011/ch1 2c rs

From Expertiza_Wiki
Jump to navigation Jump to search

Here we discuss about interfaces in Java, mixins in Ruby and compare some of the functionalities offered by mixins in Ruby and the corresponding behaviors if exhibited by the interfaces.

Interfaces in Java

An interface in java is a collection of related methods with empty bodies, constant declarations ,nested types. It is declared using a key word ‘interface’. Constants are implicitly static and final. The methods are implicitly public, an interface cannot be instantiated as it is incomplete i.e, the methods are only declared but not defined. It can only be extended by other interfaces or implemented by classes. An interface can extend any number of interfaces.

   interface <interface name>
    { <constants>
      <method declarations>
    }
   


A variable whose declared type is an interface type can hold a reference to an object of a class (or its subclass) that has implemented this interface.


Contractual Obligation: A class that implements an interface has to provide a definition for each method of the inferface or has to be declared as an abstract class if it fails to implement even one method specified in the interface. An error message is issued by the compiler if the class does not define all the methods of an interface it has agreed to define. Even unrelated classes can implement an interface.

Example of an Interface:

In the following example, we create an interface called 'Shape' with the methods 'draw' and 'displayArea'. A class 'Square' implements the interface 'Shape' by provided definitions for the methods 'draw' and 'displayArea'. In the main method we create an object of Square and call the methods. Note that a 'Shape' variable can be used to hold the reference to the object of 'Square'


            interface Shape
                {
                  void draw();  
                  void displayArea(float a,float b);
                }
            
            class Square implements Shape
             { 
                  public void draw()
                    {
                	  System.out.println("Drawing Square");
                    }
                  public void displayArea(float a,float b) 
                     { 
                          System.out.println("Area is "+a*b);
                     }

             }

           public class InfDemo
           {
                 public static void main(String args[])
                   {  Square s=new Square();
                      s.draw();
                      s.displayArea(5,5);
                   }
           }

Output:

Drawing Square
Area is 25.0 

Modules in Ruby

A Module in ruby is a way of grouping together methods,variables and classes. It is similar to the idea of namespace. A module has the same implementation and is similar to a ruby class except for a few significant differences:

  • Instance of a module cannot be created.
  • It cannot be inherited by other classes but can be included.
  • The syntax to define module is different.


Example: Consider a requirement where a person must bow to a good guy and hit the bad guy with a bow. The module 'GoodGuy' implements a method 'bow' and tells the caller to bow to the guy because he is a good guy. There is another module 'BadGuy' which implements the same method bow but tells the caller to hit the guy with a bow because he is a bad guy.

Examples of Modules:

module GoodGuy
  def GoodGuy.bow
    puts "I bow to you. you are a good guy"
  end
end

module BadGuy
  def BadGuy.bow
     puts "I will hit you with a bow.you are a bad guy"
  end
end


require 'GoodGuy' #require is used to load and execute the code once.
require 'BadGuy'
  GoodGuy.bow
  BadGuy.bow


Mixins in Ruby

History of Mixins

Mixins are not something new. Smalltalk supported them way back in 1971.According to wikipedia, Mixins first appeared in the Symbolics' object-oriented Flavors system (developed by Howard Cannon), which was an approach to object-orientation used in Lisp Machine Lisp. The name was inspired by Steve's Ice Cream Parlor in Somerville, Massachusetts The ice cream shop owner offered a basic flavor of ice cream and blended in a combination of extra items and called the item a "Mix-in", his own trademarked term at the time .

Mixins

Mixins are used to make certain behavior(s) available to a class.

Lets assume that the two modules in the above example are classes. Ruby is single-inherited, so the same functionality as above cannot be implemented through a class. Because to do so, we need to extend both the GoodGuy class and the BadGuy class which is not possible. Through modules, Ruby provides the excellent feature of multiple inheritance. Any functionality of any module can be imported into our class. Thus, the features of the module gets “mixed-in” with our class.

A class cannot inherit a module but can use the functionality of it by loading it into its definition using the ‘require’ keyword. Then, we can call all the functions in this module as if they belong to our class. If there are two modules having the same method and both modules are required by our class, the name conflict is resolved by using scope resolution operator (::)
The methods of the module do not belong to the class requiring it. In order to make a module's method the instance methods of our class, we have to use the include keyword instead of require. However, to include a module which is in a separate file, we have to use both the keywords 'require' and 'include'. Even now, it does not mean that these methods are copied into the class definition. It just references the module’s method from our class. Thus, any modifications made to the method definition in the module even at run time are reflected in the class.


Example of Mixins:

class Actnow
require 'GoodGuy'
require 'BadGuy'
def Act(kind)
if(kind=='good')
GoodGuy.bow
end
if (kind =='bad')
BadGuy.bow
end
end
end
myobj=Actnow.new
myobj.Act('good')
myobj.Act('bad')

Some Pre-defined mixin modules

Ruby has the following built into modules: Comparable, Enumerable,FileTest, GC, Kernel,Math, ObjectSpace, Preci-sion, Process, Signal.

Comparable is a mixin module which permits the including class to implement comparison operators. The including class must define the <=> operator, which compares the receiver against another object, returning -1, 0, or +1 depending on whether the receiver is less than, equal to, or greater than the other object. Comparable uses <=> to implement the conventional comparison operators (<, <=, ==, >=, and >) and the method between?.

Enumerable is a mix-in module for enumeration. The including class must provide the method each.

FileTest is a module containing file test functions; its methods can also be accessed from the File class. The GC module provides an interface to Ruby’s mark and sweep garbage collection mechanism. Some of the underlying methods are also available via the ObjectSpace module. Kernel is a module included by the Object class; it defines Ruby’s ‘built-in’ methods.

Math is a module containing module functions for basic trigonometric and transcendental functions.

ObjectSpace is a module which contains routines that interact with the garbage collection facility and allows traversing all living objects with an iterator. Precision is a mixin for concrete numeric classes with precision

Comparable Behavior

The comparable functionality is useful when there is a requirement to compare few objects and maybe even sort them.

In Ruby the comparable behavior is achieved by simply defining the <=>operator(which returns -1,0,1 depending on whether the argument object is greater than, equal to or less-than the calling object) and including the Comparable mixin. Example of Comparable in Ruby:

class Org
      include Comparable
    attr :name
    attr :revenue
    attr :emplCount
    def initialize(name,revenue,emplCount)
      @name = name
      @revenue=revenue
      @emplCount=emplCount
    end
    def <=>(second)
      self.revenue <=> second.revenue
    end
    def to_s
    "#{name}"
    end
end
org1=Org.new('org1',100000,5000);
org2=Org.new('org2',100001,4000);
org3=Org.new('org3',100002,4000);
org4=Org.new('org4',100003,4000);
org5=Org.new('org5',100004,4000);
a=[org1,org2,org3,org4,org5];
puts a.sort 

output:

org1
org2
org3
org4
org5

In Java, there is an interface called Comparable which declares an abstract method called CompareTo. Several pre-defined classes such as Float,Double,Integer,Long implement this interface and provide a definition for the CompareTo method. If we have to compare two objects of our class by comparing a specific attribute of the objects, we need to implement the interface in our class and provide the implementation of the CompareTo method by writing our code in there to compare the two objects of that class. Consider a situation where we have a class Organization and this Organization stores the information about Organizations. Suppose we have to sort different organizations as to which is greater by comparing the total revenue of each. The implementation in Java is as follows.

Example of Comparable in Java:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

//import java.util.*;
public class Org implements Comparable {
	String name;
	Integer revenue;
	int emplCount;
	public Org(String name,Integer revenue, int emplCount)
	{
		this.name=name;
		this.revenue=revenue;
		this.emplCount=emplCount;
		
	}
	public int compareTo(Object obj1)
	{
		if (this.revenue == ((Org) obj1).revenue)
	           return 0;
	       else if ((this.revenue) > ((Org) obj1).revenue)
	           return 1;
	       else
	           return -1;
	}
	 public String toString() {
	       return "Org " + name  + "\n" ;
	   }
	 public static void main(String[] args) {
	      List list1 = new ArrayList();
			Org org1=new Org("org1",1000000,5000);
			Org org2=new Org("org2",1000001,4000);
			Org org3=new Org("org3",1000002,4000);
			Org org4=new Org("org4",1000003,4000);
			Org org5=new Org("org5",1000004,4000);
			Org org6=new Org("org6",1000005,4000);
			
	list1.add(org1);
	list1.add(org2);
	list1.add(org3);
	list1.add(org4);
	list1.add(org5);
	list1.add(org6);
	      Collections.sort(list1);
	      Iterator itr = list1.iterator();
	      System.out.println("The list of organizations in the ascending order of revenue are");
	      while(itr.hasNext()){
	          Object element = itr.next();
	          System.out.println(element + "\n");   
	      }
	}
	
}

Output:

The list of organizations in the ascending order of revenue are
Org org1

Org org2

Org org3

Org org4

Org org5

Org org6


Enumerable Behavior

Enumerable module

Various operations are supported by the Ruby Collection classes .Some of such operations are traversing the collection, sorting the collection. We can define classes that can support these features on collections by including the enumerable module and defining an iterator ‘each’. This iterator has to return the elements of the collection in turn.
If the classes which have included the Enumerable module can implement the rocket method <=>, we can also use other methods like min, max ,sort on the collections.
Enumerable is a standard mixin implementing operators in terms of the ‘each’ method defined the host class. The host class is that class which includes the enumerable.
Usage of Enumerable


Ruby’s enumerable module has methods for all kinds of operations that can be performed on a collection. Collection objects which can be instances of Array,Hash etc. “mixin” the enumerable module.It gives objects of collections additional collection specific behaviors. These behaviors are given by the each method.

To Mix in Enumerable in a class,

                   Class MyCollection
                    include Enumerable
                    #other code
                     def each
                      #definiton
                     end
                   #othercode
                   end

Some of the built in classes which mixin Enumerable are : String, Hash ,Array ,Range ,Struct. Each class that includes ‘Enumerable’ must define the ‘each’ method as per its own requirement.

eg: the Array class ‘s each method yields each element.The Hash class‘s each yields each key-value pair as a two element array.


Some Useful Methods offered by Enumerable:

  • map: modifies each member according to the instructions in a block and returns the modified collection of members.
  • collect: similar to map.
  • grep: The grep method ‘searches’ for members using a regular expression

eg:

 (1..10).grep  (5..7)   #=>[5,6,7]
  • all? : It returns true if all elements of a collection satisfy the condition in the block ie the block never returns false or nil. If no block is specified it returns true if none of the collection members are false or nil.

eg:

 %w{ant bear cat}.all? {|word| word.length >= 3}   #=> true
 %w{ant bear cat}.all? {|word| word.length >= 4}   #=> false
  • any?

Passes each element of the collection to the given block. The method returns true if the block ever returns a value other than false or nil.

eg:

%w{ant bear cat}.any? {|word| word.length >= 3}   #=> true
%w{ant bear cat}.any? {|word| word.length >= 4}   #=> true


One of the common and useful methods of enumerable is ‘inject’. We can use it in any class that includes enumerable and provides the implemation for ‘each’ method. This method applies a function or operation to the first two elements in the collection and then applies the operation to the result of this computation and to the third element, and so on, until all elements in the collection have been used.

Example of using Enumerable Mixin: In the below example, the class 'EnumerableDemo' includes the Enumerable mixin and provides the definition for 'each' which yields the digits present in a string. When inject method with the argument +,is called on the object of the class it returns a string of digits.

class EnumerableDemo
 include Enumerable
    def initialize(string)
       @string=string
    end
 
    def each 
       @string.scan(/\d/) do |num|
           yield num    
    end
end


ed=EnumerableDemo.new("123Bond007")
puts ed.inject(:+)

output:

 123007 #The numbers in a string are concatinated and returned.


In Java, the Collection interface specifies some methods similar to the methods of Enumerable module. For example contains can be mapped to find,to_array can be mapped to collect. etc. But the methods are also not as powerful as those of the Enumerable module methods. Also the implementation of these methods is not available unless we inherit from a class which implements this interface. This is unlike mixins in ruby where implementation of ‘each’ method provides us several useful collection methods for free.

Enumerable Interface in Java.
Java provides the Enumeration Interface. But its functionality is different from the Enumerable module of ruby.In Java, the Enumeration interface defines the methods by which you can enumerate (obtain one at a time) the elements in a collection of objects. Successive calls to the nextElement method return successive elements of the series. For example, to print all elements of a vector v:

     for (Enumeration e = v.elements() ; e.hasMoreElements() ;) {
         System.out.println(e.nextElement());

     }


hasMoreElements: Tests if this enumeration contains more elements.
nextElement: the next element of this enumeration.

Data Mapper

In any software development, we often face situations where our code has to interact with a database. In such situations, we have to have knowledge of a query language like SQL to insert into, delete from or modify a database. In modern programming languages, a feature called Object Relational Mapping is provided. This features allow the user to access the database tuples as if they were objects. All the database operations such as insert, delete,update,etc. are implemented in the language using objects. The programmer need not have a firsthand knowledge of a query language to perform these operations.


In Ruby, Object Relational Mapping is implemented using DataMapper. The DataMapper provides wide variety of features and is thread-safe(multiple threads can call it without interfering with each other. Following are the steps involved in using the DataMapper


Step 1: Install the dm-core ruby gem – the core of the DataMapper library. This gem has no external dependencies and so, we can install it in the same way we install other gems in ruby.

$sudo gem install dm-core

Step 2: We now need to install an adapter which allows the DataMapper to talk to the database. This is specific to each database provider. '

Eg: For SQLite 3

$ sudo apt-get install libsqlite3-dev
$ sudo gem install dm-sqlite-adapter


Step 3: We then need to require the dm-core gem in our application.

Require ‘rubygems’
Require’data_mapper’
Require ‘dm-core’

Now, we have to specify the database connection to which our DataMapper must talk to. This is done using datamapper.setup


DataMapper.setup(:default, “[dataobject]://[relative-path]”)
For SQLite, this would be something like this.
DataMapper.setup( :default, "sqlite3://#databases/myown.db" )

Step-4 – Define models in a class using DataMapper:


The models can be created as below
# Create and define a class Recipee
  class Recipee
  include DataMapper::Resource

  property :Name, String: key => true
  property :type, String
  property :Description, text
 end

This model can be called using the DataMapper.auto_migrate command. This creates the table if it does not already exist. If the table already exists, it modifies the columns in this table. We can specify primary key by using the key=> true. The serial type is an auto increment integer key. We can create a column ID and define its type as serial to make it a key automatically. Now, we can access these as if they were objects without having knowledge about any query language to insert and update a table. the code

# Create a new record
myrecipee = Recipee.new
myrecipee.attributes = {
  :name => 'OrangeJuice',
  :type => 'beverage',
  :Description => 'Tasty!'
}

Insert: myrecipee.save to save

Modify: myrecipee.Description=’Tasty and Delicious!’
Delete: Myrecipee.destroy to deletethe tuple in the database

Select: puts myrecipee.inspect


DataMapper in Java
In java, Hibernate, iBatis are modern approaches that provide the ORM functionality. Traditionally, JDBC had to be used to access the databases.The functionalities provided by Hibernate are similar to that of DataMapper in ruby- it can access the database as objects.
Hibernate defines a language called HQL(Hybernate Query Language). HQL can be said to be the object oriented version of SQL. Java was created in 1995, but hibernate did not come into existence until 2001. Hibernate was developed by Redhat in Java to introduce ORM in Java.

Singleton Behavior

According to Wikipedia ,” In software engineering, the singleton pattern is a design pattern that is used to restrict instantiation of a class to one object. (This concept is also sometimes generalized to restrict the instance to a specific number of objects . This is useful when exactly one object is needed to coordinate actions across the system.”
The singleton design pattern is used when we desire only one instance of some class, such as one database connection, one logger instance or even one configuration object for an application.


In Ruby, the singleton behavior can be achieved by simply including the ‘Singleton’ Module. To use ruby singleton module,

  • ’require’ the ‘Singleton’ and then include it in desired class.
  • Use the instance method to get the instance you need.

Ruby does the following when a singleton module is included in a class.

  • New method is made private so that it can’t be used for instantiation.
  • A class method called ‘instance’ is added that instantiates only one instance of the class.

Eg

   class A
      include Singleton
      # ...
   end

this ensures that only one instance of A be created.

  a,b  = A.instance, A.instance
  a == b    # => true
  A.new               #  NoMethodError - new is private ...

Instance is created at the first call of A.instance(), thus this behavior is preserved under inheritance and cloning.This is achieved by marking A.new as private nd providing (or modifying) the class methods A.inherited() and A.clone() - to ensure that the Singletonpattern is properly inherited and cloned.

In java, the singleton design pattern proposes that at any time there can be a single instance of an object created by JVM. To implement this behavior, the class’s default constructor is made private. This prevents the direct instantiation of the object. A static modifier is applied to the instance method that returns the object as it then makes this method a class level method that can be accessed without creating an object.

For implementing a singleton pattern, consider the following steps:
Step -1: Provide a default private constructor.
Step-2: Define a method to obtain the reference to the singleton Object.
Step 3: The Access method has to be made synchronized to prevent Thread Problems.
Step 4: The Object clone method has to be overridden to prevent cloning.

Example of Singleton:

class SingletonClass {

	private static SingletonClass singletonObject;
	/** A private Constructor prevents any other class from instantiating. */
	private SingletonClass() {
		//	 Optional Code
	}
	public static synchronized SingletonClass getSingletonObject() {
		if (singletonObject == null) {
			singletonObject = new SingletonClass();
		}
		return singletonObject;
	}
	public Object clone() throws CloneNotSupportedException {
		throw new CloneNotSupportedException();
	}
}

public class SingletonObjectDemo {

	public static void main(String args[]) {
		//		SingletonClass obj = new SingletonClass();
                //Compilation error not allowed
		SingletonClass obj = SingletonClass.getSingletonObject();
		// Your Business Logic
		System.out.println("Singleton object obtained");
	}
}


Mixin vs Interfaces

  • What makes mixins so powerful is that the methods of the host class(the class that includes the module) can be accessed in the module even before we define the host class.

Example: In the following example,we define a module 'Wisher' which defines a method 'wish' that uses a method 'name' of the host class . Next we define the host class (Person) that includes 'Wisher' and hence obtains the 'wish' method of the module.The 'Person' class contains an attribute reader method 'name' and an initialize method. We then create an object 'p' of class 'Person' and call the method 'wish' on it.The 'wish' method uses method 'name' of Person to return a string as the output.

module Wisher
  def wish
   puts "Good Day "+self.name  #name ie attr_reader method of the host class is used even before the class is define.
  end
end

 class Person
    include Wisher
  def initialize(name,age)
    @name=name
    @age=age
  end
    attr_reader :name
 end

p=Person.new (“James”,4)
p.wish   #returns Good Day James.

Such a feature is not supported by interfaces in java.

  • Rewriting : When an interface is rewritten, all classes that implemented the older version are now broken because they no longer implement the interface. Hence the programmer has to try to anticipate all uses for the interface he/she is defining and specify it completely from the beginning. Such a problem is not caused in Ruby. Even if the module definition is changed at run-time, the classes that include the module use the modified version of the module.
  • Both Java and Ruby support single inheritance.i.e, A class can inherit features from a single class. Multiple inheritance is achieved in Java through interfaces and in Ruby through Mixins. ie A java class can extend only one class but can implement several interfaces. Hence objects can have multiple types ie the type of their own class and the type of the interfaces that their class Similarly a Ruby class can be subclassed from a single class but can include many modules.(mixins). In Ruby, inheritance and mixins allow us to write code at one place and reuse it in other classes. Inheritance is used when there is an “is-a” relationship. Mixins are used when there is a “uses a” or “has a” relationship. However there is no such advantage with interfaces in java . Hence there can be misuse of inheritance as even unrelated classes can implement an interface.
  • One analogy that can be used to compare interfaces in java and mixins in ruby is that interface is like a legal contract while mixin is like a promise. ie a java interface is all about meeting the rules of the extra methods that must be provided where as in ruby there are no such rules to be enforced. Consider the comparable behavior for example. Both mixin and the interface provide similar behavior. But if a class extends' Comparable' interface but fails to implement the 'compareTo' method a compile time error occurs even if the object of the class does not attempt to use the comparable behavior. But in cases of mixins, if a class includes ‘Comparable’ mixin and does not implement the <=> method there are no errors if the object of the class does not attempt to use the comparable behavior. Hence we can think of it as a promise. If the object uses the comparable behavior ie calls methods like >,<,between? Etc then an runtime error occurs.


eg: Consider the class 'A' which includes the 'Comparable' mixin.It defines a method 'hi'. It does not implement the <=> method. When an object 'a' of class 'A' is created and method 'hi' is invoked on it, there is no exception. But there will be a exception when the methods like <,>etc are used because the <=> method has not been implemented.

class A
  include Comparable
 def hi
    puts "hi"
 end
end

 a=A.new

 a.hi  #returns  “hi”.  In java,there would be a compilation error in such a scenario since the methods of the Interface are not implemented.
  • Also classes implementing interfaces do not inherit code; it is purely something to help more programs type-check in a statically typed language whereas mixins provide actual code to classes that include them. Hence mixins allow code reusability.

Conclusion

We have seen that some of the functionality of mixins is provided by interfaces in Java like the Comparable functionality for instance. However,we know that an interface only specifies what the class must support and cannot provide an implementation unlike a module which can be mixed into any number of classes. For refactoring common behavior into a single place in java to achieve the power of mixins,we need another class which provides an implementation and is dependent on the interface.It has been observed that Interfaces when combined with aspect-oriented programming can produce full fledged mixins in Java.

References:

http://ruby.about.com/od/sinatra/a/datamapper.htm .
http://solitude.vkps.co.uk/Archives/2009/01/13/data-mappers/
http://javatemple.blogspot.com/2008/11/features-of-hibernate-in-nutshell.html
http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Comparable.html
http://www.tutorialspoint.com/ruby/ruby_modules.htm
http://www.javabeginner.com/learn-java/java-singleton-design-pattern
http://www.brainbell.com/tutorials/java/Applying_Some_Structure.htm
http://ruby-doc.org/
http://download.oracle.com/javase/tutorial
http://en.wikipedia.org/wiki/Mixin
http://en.wikipedia.org/wiki/Singleton_pattern