CSC/ECE 517 Fall 2012/ch1a 1w16 br

From Expertiza_Wiki
Jump to navigation Jump to search

Overview

Mixins are Ruby modules. A module is a grouping of objects under a single name. The objects may be constants, methods, classes, or other modules. Modules are defined in Ruby using the keyword module. They can be incorporated into a class with Ruby’s include statement. This is called a mixin. Modules are for sharing behavior (methods), while classes are for modeling relationship between objects. Ruby classes can Mixin a module and receive all its methods for free. An Interface in Java programming language is an abstract type that classes must implement. Interfaces are declared using the interface keyword, and may only contain method signature and constant declarations. A class that implements an interface must implement all of the methods described in the interface, or be an abstract class.

Definitions

Mixins

Modules provide a structure to collect classes, methods, and constants into a single, separately defined unit. They provide the simplest and an elegant way to adhere to the Don't repeat yourself<ref>Don't_repeat_yourself</ref> principle. This is useful so as to avoid clashes with existing classes, methods, and constants. Modules are defined in Ruby using the module keyword. A Mixin is a class that is mixed with a module or a set of modules i.e. the implementation of the modules and the class are intertwined and combined together <ref>Mixins </ref>. This gives us a neat and controlled way of adding new functionality to classes. Modules are similar to classes in that they hold a collection of methods, variables constants and other modules and class definitions. However, the real usage of a Mixin is exploited when the code in the Mixin starts to interact with code in the class that uses it. Below is an example for modules and Mixins: The module ParkingSlot consists of the methods park and unpark

module ParkingSlot
      def park
         #code to park the car
      end
      def unpark
         #code to unpark the car
      end
end

The module ParkingMeter consists of the methods calculate and printreceipt

module ParkingMeter
      def calculate
         #code to calculate the parking fee
      end
      def printreceipt
         #code to print the receipt
      end
end

When a class includes a module via include Module Name, all the methods on that module become instance methods on the class.

class Parking
     include ParkingSlot
     include ParkingMeter
     def printcardetails
         #code to print the details and type of car
     end
end

The modules ParkingSlot and ParkingMeter are “included” in the Parking class. All the variables and the instance methods of the modules ParkingSlot and ParkingMeter are now said to be “mixed in” into the class. It is now possible for class instances to use these methods defined in the modules as and when required.

p=Parking.new   
p.park            # -> Method park from module ParkingSlot
p.unpark          # -> Method unpark from module ParkingSlot
p.calculate       # -> Method calculate from module ParkingMeter
p.printreceipt    # -> Method printreceipt from module ParkingMeter
p.printcardetails # -> Calls printCarDetails from class

The class Parking inherits from both the modules and the module methods are now available in Parking. Hence, it is now possible to use the methods with an instance of the Parking class p. Hence, Mixins can be thought of taking different methods and variables defined in different modules making them available as instance methods in the class as well, thereby extending the class’ functionality. Effectively mixed in modules behave as superclass.


Interfaces

In object-oriented programming languages such as Java, C#, an interface<ref>Interfaces </ref> is a reference type, similar to a class that can contain only constants, method signatures, and nested types. There are no method bodies. Interfaces cannot be instantiated and they can only be implemented by classes or extended by other interfaces. All methods are public by default and any fields declared in an interface are by default static and final. Example:

public interface ParkingLot {
      boolean add(Car car, int slot);
      boolean remove(Car car);
      boolean findCar(Int number);
      int freeSlotsCount();
      int occupiedSlots();
      int parkingType();
      int calculateParkingFee(int hours, int charge, int duration);
      int findParkingSlot();
}
public class Mall implements ParkingLot {
      boolean add(Car car, int slot) { //... Code to add a car into the parking lot... }
      boolean remove(Car car){ // do something }
      boolean findCar(Int number){ // do something }
      int freeSlotsCount(){ // do something }
      int occupiedSlots(){ // do something }
      int parkingType(){ // do something }
      int calculateParkingFee(int hours, int charge, int duration){ // do something }
      int findParkingSlot(){ // do something }
}

Interfaces play another important role in the object-oriented programming language. Interfaces are not part of the class hierarchy, although they work in combination with classes.

Mixins vs. Interfaces

Similarities and Differences

Mixins and Interfaces can be considered as a block of code having some variables and methods that can be used by a class. The difference between them is that a Mixin can contain method definitions whereas an Interface cannot.

Multiple method definition

In a class, when more than one module is mixed in where some modules have overloaded methods, the method from the module that was last mixed in into the class will be executed.

module Frog
   def sound()
     puts "croak..."
    end
end
module Dinosaur
  def sound()
    puts "roar..."
  end
end
class Frogosaur
      include Frog
      include Dinosaur
end
Frogosaur.new.sound 
Output:
roar...

This is because the class Frogosaur can contain only one definition for each method. The users have the flexibility to make use of methods from different modules by rearranging the order of include. Interfaces, on the other hand, do not offer the flexibility to have different implementation for a same method. This is because the class implementing the interface can provide only one implementation for each method. Hence they offer only one method definition for the user.

public interface Frog {
    void sound();
}
public interface Dinasour {
    void sound();
}
public class Frogosaur implements Frog,Dinasour{
public void sound()
{
    System.out.println("barks......");
}
public static void main(String args[])
{
    new Frogosaur().sound();;
}
}
Output:
barks...

Multiple object behavior

In Ruby, a class’s instance can extend a module and exhibit different behavior than the other instances of the same class.

module Frog
 def sound()
    puts "croak..."
  end
end
module Dinasour
 def sound()
   puts "roar..."
 end
end
class Frogosaur
 def sound()
   puts "barks..."
 end
end
beast1= Frogosaur.new
beast2= Frogosaur.new
beast1.extend(Frog)
beast1.sound
beast2.sound
Output:
croak...
barks...

Interfaces are implemented by a class and all instances of the class behave in the same way. They can only use the methods of the class to which they belong to.

public class Frogosaur implements Frog,Dinasour{
 public void sound()
 {
     System.out.println("Sounds...");
 }  
 public static void main(String args[])
 {
     Frogosaur beast1 = new Frogosaur();
     Frogosaur beast2 = new Frogosaur();
     object1.sound();
     object2.sound();
 }
}
Output:
Sounds...
Sounds...

Enumerable – module and interface

Ruby’s Arrays have several methods defined in them. To use them, the classes need not be a subclass of Array. The classes can include Enumerable <ref>Enumerables</ref> and define the each method to use the array’s methods for free.

class EnumExer
 include Enumerable
 def initialize(*arrays)
   @arrays = arrays
 end
 def each
   @arrays.each { |a| a.each { |x| yield x } }
 end
end
ma = EnumExer.new([4, 1], [3], [2])
puts ma.sort
Output:
1
2
3
4

You can observe that although the arguments passed to the ma instance did not have a similar structure, the sort method was able to identify each entry and sort them. This is because the each method was defined to identify and serve all the entries to the sort method. The methods that are defined for Enumerable modules are:

["all?", "any?", "collect", "detect", "each_with_index", "entries","find", "find_all", "grep", "include?", "inject",
"map", "max","member?", "min", "partition", "reject", "select", "sort", "sort_by","to_a", "zip"]

In Java, to use the methods of Enumerable interface, the class should be a subclass of Array.

public class EnumExer {
    static String content_string = "zyxwvutsrqponmlkjihgfedcba";
    String a="1", b="2";
    public static void main(String args[])
    {
        char[] content_array = content_string.toCharArray();
        java.util.Arrays.sort(content_array);
        content_string=new String(content_array);
        System.out.println(content_string);
    }
}
Output:
Abcdefghijklmnopqrstuvwxyz

In the above example, the string object was converted to a character array to be able to use with the sort method.

Inheritance

Java interfaces can inherit other interfaces whereas Ruby modules cannot although they can contain classes and methods.

module Wrapper
 class Base
    # Class Body
 end
end
public interface Dinasour extends Frog{
    //variables and method Declarations
}

Achieving Multiple Inheritance

Modules and Interfaces help acheive multiple inheritance.
Interfaces are used in Java to achieve multiple inheritance<ref> Mulitple Inheritance </ref>. Similarly, modules in Ruby help achieve multiple inheritance.

In Ruby,

module Frog
  def jump()
    //Method definition
   end
end 
module Dinosaur def strength() //Method definition end end
class Frogosaur include Frog include Dinosaur end

In Java,

public interface Frog {
    void jump();
} 
public interface Dinasour { void strength(); }
public class Frogosaur implements Frog,Dinasour{ //Method Implementations }

Frogosaur inherits the methods of both frog and dinosaur.

Comparison

Mixins Interfaces
The number of lines of code is lesser since the

modules contain method definitions.

The number of lines of code is bigger since the

classes have to define the methods.

More modules in a class makes code less readable. The code is more readable since the class contain the

method definition.

Modules cannot be inherited and cannot form is-a hierarchy. Interfaces can extend another interface and hence can form

is-a hierarchy.

Drawbacks

The drawbacks of the technique of Mixins are very much debated. Though Mixins provide us with an easy way to write flexible and decoupled code they pose their own problems. In large programs there could be large number of modules and each module could have loads of methods each performing a certain task. To trace the origin of the methods and to remember the hierarchy is difficult. Mixins suffer from silent method overriding. Silent method overriding refers to a condition when different modules are included in a class and each module have a method with the same definition. In such a case, the method which gets executed depends upon the way it is included in the class and this is done without any sort of message to the user (silently). In large scale applications this could certainly be an issue considering the number of modules that would be mixed in and it would be difficult to keep track of the hierarchy in which the modules were included. Although Java provides polymorphic behavior with the use of interfaces, they sometimes tend to be very slow. The implementation of interfaces is also limited to public methods and constants with no implementation.

Conclusion

Modules and Interfaces are similar in the fact that they enable additional features in object-oriented programming languages. They are dissimilar in the way they are implemented but add more flexibility to object-oriented programming and are easy to maintain.

References

<references/>

See Also

1. http://ruby.about.com/od/beginningruby/a/mixin.htm/
2. http://juixe.com/techknow/index.php/2006/06/15/mixins-in-ruby/
3. http://www.innovationontherun.com/why-rubys-mixins-gives-rails-an-advantage-over-java-frameworks/
4. http://pg-server.csc.ncsu.edu/mediawiki/index.php?title=CSC/ECE_517_Fall_2010/ch3_3b_sv&printable=yes
5. http://expertiza.csc.ncsu.edu/wiki/index.php/CSC/ECE_517_Fall_2011/ch2_2c_ds
6. Lucas Carlson; Leonard Richardson (July 2006), Ruby Cookbook, O'Reilly Media, ISBN 10:0-596-52369-6