CSC/ECE 517 Fall 2010/ch6 6a PC: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
 
(191 intermediate revisions by 2 users not shown)
Line 7: Line 7:
= Introduction =
= Introduction =


Dictionary defines delegation as the assignment of authority and responsibility to another person to carry out specific activities.In programming context it is nothing different. It is basically entrusting an action to another agent. Lieberman in his 1986 paper "Using Prototypical Objects to Implement Shared Behavior in Object-Oriented Systems"[http://portal.acm.org/citation.cfm?id=28718] defines delegation in object oriented languages as a programming language feature making use of the method lookup rules for dispatching so-called self-calls.
Dictionary defines delegation as the assignment of authority and responsibility to another person to carry out specific activities. In simple words, it means "passing a duty off to someone or something else".
 
In programming context it is nothing different. It is basically entrusting an action to another agent. The term Delegation was initially introduced by Henry Lieberman in his 1986 paper "Using Prototypical Objects to Implement Shared Behavior in Object-Oriented Systems"[http://portal.acm.org/citation.cfm?id=28718 [1]] He defines delegation in object oriented languages as a programming language feature making use of the method lookup rules for dispatching so-called self-calls.
 
[[Image:Delegation_self.jpg]]
 
The above diagram depicts that a message receiver is asking another object (message holder) to do something on its behalf which may delegate it to someone and so on and so forth.[http://javalab.cs.uni-bonn.de/research/darwin/delegation.html [2]]
 
Hence delegation means simply passing off a task to someone else so as to complete it on its behalf.
 


== Delegation ==
== Delegation ==


[http://en.wikipedia.org/wiki/Delegation_(programming) Delegation], is also referred to as [http://en.wikipedia.org/wiki/Object_composition#Aggregation aggregation],consultation, or forwarding. In delegation one class may contain an instance of another class, and <i>delegate</i> some responsibility to that class. This is also referred to as the [http://en.wikipedia.org/wiki/Has-a has-a] relationship. Aggregation should not be confused with [http://en.wikipedia.org/wiki/Object_composition composition]. Both aggregation and composition are used to describe one object containing another object, but composition implies ownership [http://en.wikipedia.org/wiki/Object_composition#Aggregation]. Aggregation is more general and doesn't imply any responsibilities for memory management. A class which contains other classes is called a <i>composite</i> class, while a class being contained is called a <i>composited</i> or <i>composed</i> class [http://en.wikipedia.org/wiki/Object_composition].Delegation is a very powerful reuse technique. The provides run time flexibility. It is also called dynamic inheritance.[http://www.ccs.neu.edu/research/demeter/papers/context-journal/node3.html] 
Delegation is a simple yet, powerful concept of handing a task over to another part of the program. In object-oriented programming it is used to describe the situation wherein one object defers a task to another object, known as the delegate. Thus delegation is like inheritance done manually through object composition.
Thus it refers to one object relying upon another to provide a specified set of functionalities.


Delegation based languages-
[http://en.wikipedia.org/wiki/Delegation_(programming) Delegation], is also referred to as [http://en.wikipedia.org/wiki/Object_composition#Aggregation aggregation],consultation, or forwarding. In delegation one class may contain an instance of another class, and <i>delegate</i> some responsibility to that class. This is also referred to as the [http://en.wikipedia.org/wiki/Has-a has-a] relationship. Aggregation should not be confused with [http://en.wikipedia.org/wiki/Object_composition composition]. Both aggregation and composition are used to describe one object containing another object, but composition implies ownership. Aggregation is more general and doesn't imply any responsibility for memory management. A class which contains other classes is called a <i>composite</i> class, while a class being contained is called a <i>composited</i> or [http://en.wikipedia.org/wiki/Object_composition <i>composed</i>] class.
* '''Meta-language''' is the language in which meta-programs, which construct or manipulate other programs, are written.  
* '''Object-language''' is the language of programs being manipulated.  
This makes them ‘meta level programs’ whose problem domain are other ‘base level programs’.


[[Image:Meta_1.jpg]]
Delegation is a very powerful reuse technique. It provides run time flexibility. It is also called [http://www.ccs.neu.edu/research/demeter/papers/context-journal/node3.html dynamic inheritance].


The ability of a programming language to be its own metalanguage is called reflection or reflexivity.
Delegation can be implemented in many programming languages like Ada, Aikido, C, C#, C++, Common Lisp, D, E, Go, J, Java, JavaScript, Logtalk, Objective-C,Oz, Perl,Perl 6, PHP, PicoLisp, Pop11, Python, Ruby, TCL, Vorpal[[http://rosettacode.org/wiki/Delegate [3]]


Simple example of a metaprogram:
Example in a Java like language:
<br>Let us consider a totally fabricated example for our understanding at very high level. Suppose we need to write a C program that printed the following 500 lines of text with a restriction that the program could not use any kind of loop or goto instruction.


Output expected:
class Delegate
{
    void doSomething()
    {
        // "this" is also known as "current", "me" and "self" in other languages
        this.callMe()
    }
    void callMe()
    {
        print("I am Delegate")
    }
}


  1 Mississippi
class Delegator
  2 Mississippi
{
  3 Mississippi
    private Delegate d;  // delegationlink
  4 Mississippi
    public Delegator(Delegate d)
  ...
    {
  499 Mississippi
        this.d = d;
  500 Mississippi
    }
    void doSomething() {
        d.doSomething() // call doSomething() on the Delegate instance
    }
    void callMe() {
        print("I am Delegator")
    }
}
d = new Delegate()
b = new Delegator(d) // establish delegation between two objects


In C this would be then coded as:


  #include <stdio.h>
Here calling b.doSomething() will result in ''"I am Delegate"'' being printed, since class Delegator "delegates" the method callMe() to a given object of class Delegate.
  int main(void) {
    printf("1 Mississippi\n");
    printf("2 Mississippi\n");
        -
        -
        -
    printf("499 Mississippi\n");
    printf("500 Mississippi\n");
    return 0;
  }


With the power of a metaprogramming language we can write another program that writes this program automatically.
== Delegation vs Inheritance ==
Ruby code:


  File.open('mississippi.c', 'w') do |output|
Inheritance :
  output.puts '#include <stdio.h>'
* [http://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming) Inheritance] is restricted to compile time
  output.puts 'int main(void) {'
* Since it targets type rather than instances, it cannot be removed/changed at runtime
    1.upto(500) do |i|
* Inheritance can be statically type-checked
      output.puts "    printf(\"#{i} " +
      "Mississippi\\n\");"
  end
  output.puts '    return 0;'
  output.puts '}'
  end


This code creates a file called mississippi.c with the expected 500+ lines of C source code.Here, mississippi.c is the generated code and ruby code is the metaprogram.
Delegation:
* Delegation takes place at run-time
* Since it takes place at run-time, it can even be removed at run-time
* Cannot guarantee static type-safety (By using interfaces, delegation can be made more flexible and typesafe)


== Applications of Metaprogramming ==


Metaprogramming is an attractive technique needed when one needs to alter the behavior of a program at run time. Due to its generative nature, it has numerous applications in program development. It can achieve program development without rewriting boiler-plate code [http://en.wikipedia.org/wiki/Boilerplate_text] all the time, ensuring efficiency, increasing modularity and minimizing inconsistent implementation errors. Program generators and program analyzers are the two main categories of meta programs. Metaprograms can be compilers, interpreters, type checkers etc. Some commonly used applications include using a program that outputs source code to -
Hints to use Inheritance
* generate sine/cosine/whatever lookup tables
* Inheritance is used to create sub-categories of objects
* to extract a source-form representation of a binary file
* Mostly identified in 'is-a' relationships between objects
* to compile your bitmaps into fast display routines
* Inheritance is used when two objects are of the same type but one of the objects may need to have its own customized functionality. The child object just inherits from the parent and writes its own implementation of the feature it needs extra.
* to extract documentation, initialization/finalization code, description tables, as well as normal code from the same source files
* Inheritance can be implemented on objects of the same type only.
* to have customized assembly code, generated from a perl/shell/scheme script that does arbitrary processing
* to propagate data defined at one point only into several cross-referencing tables and code chunks.  


Programmers can focus more on the main business logic and new features to be implemented rather than writing repetitive chunks of code (e.g. setups, stubs)[1].
[[ Image:Inheritance_db_newtable.gif ]]
 
Here we have an abstract base class. We extend this to to provide something that we can represent any product. We then provide a few specialisations for typical products like book,cd.This is a usual case when inheritance is used.


= Typing in Programming Languages =
Hints to use Delegation
* Delegation is used when two objects aren't of the same type but one has methods and attributes that the other wants to use internally instead of writing its own implementation
* Identified as 'as-a' relationships where the type of included object may change during runtime.
* Delegation is used when methods implementation needs to be handled by some other class within the parent tree. The class that will handle the method isn't known at compile time.
* Code execution within objects needs to be determined dynamically.


Earlier programming languages [e.g. Assembly] were written such that each machine level function was reflected in the program code. With advancement in programming languages a certain level of abstraction was reached wherein lower level details were abstracted with one functional unit of work and represented by fewer lines of code e.g. primitive variables are represented with higher level abstract classes. With this abstraction arose a need for checking the validity of operations that could be performed with these abstractions in place.
[[ Image:Delegation.jpg ]]


Typing in programming languages is property of operations and variables in the language that ensure that certain kinds of values that are invalid are not used in operations with each other. Errors related to these are known as type errors. Type checking is the process of verifying and enforcing the constraints of types. Compile time type checking also known as static type checking. Run time type checking is known as dynamic type checking. If a language specification requires its typing rules strongly (i.e., more or less allowing only those automatic type conversions which do not lose information), one can refer to the process as strongly typed, if not, as weakly typed.[http://en.wikipedia.org/wiki/Type_system]
In the above diagram, class C inherits from A. Also, class C has a method called as Call which simple calls the method Call from class B. Hence, class C is delegating its functionality to be implemented by Class B. For this, class C has an object reference to class B.[http://www.khelll.com/blog/ruby/delegation-in-ruby/ [4]]
The above classification can be represented as -


= Situations where you can use delegation =


[[Image:Meta_2.jpg]]
Consider following situation[http://www.khelll.com/blog/ruby/delegation-in-ruby/ [4]]:


== Statically Typed Programming Languages ==
* Objective: We want a robot to have a heat sensor capability.
* Initial design: So we initially decide to build a Robot class like the one shown below:


Statically typed languages ensure that a fixed type is assigned by the programmer to every variable and parameter. Thus, every expression type can be deduced and type checked during compilation. Static languages try to fix most errors during compile time and strive to minimize failures during run time. Due to this there are many type constraints on the programmer while coding.  At run time, the program uses the classes that it has been given and in this way statically typed languages make distinctions between what happens at compile time and what happens at run time. Examples of statically typed languages are C, C++, Java, C#.
[[ Image:robotclass.jpg]]


== Dynamically Typed Programming Languages ==
* Problem with the design: Now all Robots should have a heat sensor. What if some robot did not have a heat sensor capability?
* Solution: So we make a Robot base class and a VolcanoRobot class which inherits from Robot and performs the heat-sensor operations


In dynamically typed languages, the variables and parameters do not have a designated type and may take different values at different times. In all the operations, the operands must be type checked at runtime just before performing the operation. Dynamically typed languages don’t need to make a distinction between classes created at compile time and classes provided.  It is possible to define classes at run time and in fact, classes are always defined at run time. These eliminate many developer constraints by avoiding the need of book keeping, declarations etc. Due to this flexibility these languages make an ideal candidate for prototyping and are widely used in agile development environments. However, dynamic languages are known to have performance issues. Static languages have code optimization features at compile time, but dynamic languages allow runtime code optimizations only. [http://www.slideshare.net/aminbandeali/dynamically-and-statically-typed-languages] In dynamically typed languages,  the interpreter deduces type and type conversions, this makes development time faster, but it also can provoke runtime failures. These runtime failures are caught early on during compile time for statically typed languages.
[[ Image:volcanoclass.jpg]]
Examples of dynamically typed languages include Perl, Python,  JavaScript, PHP, Ruby, Groovy.


= Metaprogramming in statically typed languages =


In safety languages [syntactically verbose], metaprogramming is not a standard feature, it can however be achieved. Also, static typing in meta-programs has a number of advantages. In addition to guaranteeing that the meta-program encounters no type-errors while manipulating object-programs, a statically typed metaprogramming language can also guarantee that any of the object-programs generated by the meta-program are also type-correct. A disadvantage of these type system is that (in case of meta-programming languages with weaker type systems) they sometime may be too restrictive in object-programs that the programmer is allowed to construct.
* Problem: But with this design whenever we want to modify anything related to the heat sensor, we will have to change the robot class. Also, with our design we have exposed heat sensor methods to Robot class.
* Solution: Hence, in such situations delegation is best.  


== Techniques and Packages ==
[[ Image:Ruby_delegation.jpg]]


Many language features can be leveraged to achieve some form of characteristics needed to achieve metaprogramming. For instance, languages that support  reflection also allow for dynamic code generation.  e.g. In Microsoft .NET Framework use of "System.Reflection.Emit" namespace is used to generate types and methods at runtime.  
* New design: Delegate the heat sensor functionality to Heat Sensor class. VolcanoRobot still has the 3 methods that are related to the sensor, but those are wrapper methods, they do nothing but to call the sensor corresponding ones, and that’s exactly what delegation is, just delegate functionality to the contained parts(delegates).


=== Reflection ===
Delegation and composition go hand in hand to provide a flexible neat solution and also it serves the principle “separate changeable code from static one” .  The price that one needs to pay for this is that we need wrapper methods, and extra time needed in processing because of the call of these wrapper methods.


Reflection is a valuable language feature to facilitate metaprogramming. Reflection is defined as the ability of a programming language to be its own meta-language. Thus, reflection is writing programs that manipulate other programs or themselves. [http://www.developer.com/java/web/article.php/3504271/Java-Reflection-in-Action.htm] <br>
e.g. In Java, reflection enables to discover information about the loaded classes:
* Fields,
* Methods and constructors
* Generics information
* Metadata annotations
It also enables to use these metaobjects to their instances in run time environment.
E.g. Method.invoke(Object o, Object… args)
With the Java reflection API, you can interrogate an object to get all sorts of information about its class.


Consider the following simple example: 
  public class HelloWorld {
    public void printName() {
      System.out.println(this.getClass().getName());
    }
  }


The line
== Delegation Design Pattern ==
  (new HelloWorld()).printName();
sends the string HelloWorld to standard out. Now let x be an instance of HelloWorld or one of its subclasses. The line
  x.printName();
sends the string naming the class to standard out.


The printName method examines the object for its class (this.getClass()). In doing so, the decision of what to print is made by delegating to the object's class. The method acts on this decision by printing the returned name. Without being overridden, the printName method behaves differently for each subclass than it does for HelloWorld. The printName method is flexible; it adapts to the class that inherits it, causing the change in behavior.
It is a design pattern in object oriented languages where an object expresses certain behavior to the outside but in reality delegates responsibility for implementing that behaviour to an associated object.


=== Annotations ===
Consider the following examples in java:


Annotations are a metaprogramming facility that allow the code to be marked with defined tags. Many APIs require a fair amount of boilerplate code. This boilerplate could be generated automatically by a tool if the program were “decorated” with annotations indicating which methods were remotely accessible. Metadata provided using annotations is beneficial for documentation, compiler checking, and code analysis. One can use this metadata to indicate if methods are dependent on other methods, if they are incomplete, if a certain class must reference another class, and so on. It is used by the compiler to perform some basic compile-time checking. For example there is a override annotation that lets you specify that a method overrides another method from a superclass. At this, the Java compiler will ensure that the behavior you indicate in your metadata actually happens at a code level as well.
class Subordinate  // the "delegate"
    void performTask()
    {
      System.out.print("Subordinate is performing");
    }
}
class Manager // the "delegator"
{
    Subordinate slave = new Subordinate();  // create the delegate
    void performTask()
    {
      slave.performTask(); // delegation
    }
}
public class Main {
    // to the outside world it looks like Manager is actually doing work.
    public static void main(String[] args) {
        Manager boss = new Manager();
        boss.performTask();
    }
}


An “annotation” has an “annotation type” associated with it which is used for defining it. It is used when you want to create a custom annotation. The type is the actual construct used, and the annotation is the specific usage of that type. An annotation type definition takes an "at" (@) sign, followed by the interface keyword plus the annotation name. On the other hand, an annotation takes the form of an "at" sign (@), followed by the annotation type [http://www.developer.com/java/other/article.php/3556176/An-Introduction-to-Java-Annotations.htm].
== Delegation as a Language Feature ==


Example to Define an Annotation (Annotation type)
Prototype-based programming is a classless type of Object oriented programming technique which performs the work of inheritance in class-based languages.  Delegation is the language feature that supports [http://en.wikipedia.org/wiki/Prototype-based_programming  prototype-based programming]. It is the mechanism by which code is selected for execution in a dynamic way. Delegation is the process by which a function or method, referred to in the context of one object, is found in another object. When a method is referred to by code defined for an object but is not itself found to be defined in the object the language runtime searches other objects, called [http://en.wikipedia.org/wiki/Prototype-based_programming#Delegation delegates]. Depending on the object model of the individual language the delegates may defined when the object is created or may be specified by the method-call syntax. The analogous process in a class-based language is dispatching to an inherited method, and an object's delegates perform the role of superclasses in a class-based language.
 
  public @interface MyAnnotation {
    String doSomething();}
  Example to Annotate Your Code (Annotation)
  MyAnnotation (doSomething="What to do")
  public void mymethod() {
  ....
  }


==== Annotation Types ====
= Delegation in Ruby =
There are three annotation types:
* '''Marker:''' Marker type annotations have no elements, except the annotation name itself.
Example:
  public @interface MyAnnotation {
  }
Usage:
  @MyAnnotation
  public void mymethod() {
  ....
  }


* '''Single-Element:''' Single-element, or single-value type, annotations provide a single piece of data only. This can be represented with a data=value pair or, simply with the value (a shortcut syntax) only, within parenthesis.
Delegation pattern in Ruby is implemented in 2 ways [http://www.scribd.com/doc/27239260/Rails-Magazine-Issue-1-The-Beginning [5]]:
Example:


  public @interface MyAnnotation
1)'''Forwardable lib:'''[http://www.ruby-doc.org/stdlib/libdoc/forwardable/rdoc/index.html Forwardable lib] is a library that supports delegation. It has two modules
  {
* Forwardable
    String doSomething();
* SingleForwardable:
  }


Usage:
Forwardable module:-
  @MyAnnotation ("What to do")
  public void mymethod() {
  ....
  }


* '''Full-value or multi-value:''' Full-value type annotations have multiple data members. Therefore, you must use a full data=value parameter syntax for each member.
Using the methods def_delegator and def_delegators the Forwardable module provides delegation of specified methods to a designated object.
Example:
  public @interface MyAnnotation {
    String doSomething();
    int count; String date();
  }
Usage:
  @MyAnnotation (doSomething="What to do", count=1,
              date="09-09-2005")
  public void mymethod() {


=== Generics ===
* def_delegator(obj, method, alias = method) : Defines a method method which delegates to obj. If alias is provided, it is used as the name for the delegate method.


Generic programming is a style of computer programming in which algorithms are written in terms of to-be-specified-later types that are then instantiated  when needed for specific types provided as parameters. [http://en.wikipedia.org/wiki/Generic_programming] Java Generics are primarily a way for library authors to write something once, which users can customize to their own types. They allow the creation of classes and methods that work in the same way on different types of objects. The term "generic" comes from the idea that we'd like to be able to write general algorithms that can be broadly reused for many types of objects rather than having to adapt our code to fit each circumstance.
* def_delegators(obj, *methods): Shortcut for defining multiple delegator methods, but with no provision for using a different name.


Generics add a way to specify concrete types to general purpose classes and methods that operated on object before. A Java collection is a flexible data structure that can hold heterogeneous objects where the elements may have any reference type. When you take an element out of a collection, you must cast it to the type of element that is stored in the collection. Generics provides a way for you to communicate the type of a collection to the compiler, so that it can be checked. Once the compiler knows the element type of the collection, the compiler can check that the collection has been used consistently and can insert the correct casts on values being taken out of the collection.[5] Generics are implemented by type erasure: generic type information is present only at compile time, after which it is erased by the compiler. The main advantage of this approach is that it provides total interoperability between generic code and legacy code that uses non-parametrized types (which are technically known as raw types).
SingleForwardable module:-


Consider a non-generic example:
Using the methods def_delegators, the [http://www.ruby-doc.org/stdlib/libdoc/forwardable/rdoc/classes/SingleForwardable.html SingleForwardable] module provides delegation of specified methods to a designated object. This module is similar to Forwardable, but instead of their defining classes, it works on objects themselves.
  //This program removes 4-letter words from c. Elements must be strings
  static void expurgate(Collection c) 
  {   
        for (Iterator i = c.iterator(); i.hasNext(); )     
        if (((String) i.next()).length() == 4)       
        i.remove();
    }
Here is the same example modified to use generics:
  //This program removes the 4-letter words from c
  static void expurgate(Collection<String> c)
  {   
    for (Iterator<String> i = c.iterator(); i.hasNext(); )
    if (i.next().length() == 4)
    i.remove();
  }
The declaration above reads as “Collection of String c.” Collection is a generic class that takes ‘String’ as its type parameter. The code using generics is clearer and safer. Unsafe cast and a number of extra parentheses have been eliminated. More importantly, we have moved part of the specification of the method from a comment to its signature, so the compiler can verify at compile time that the type constraints are not violated at run time.[http://www.cs.tut.fi/~kk/webstuff/MetaProgrammingJavaKalvot.pdf]


=== Template Metaprogramming ===
2)'''Delegate lib:'''[http://www.ruby-doc.org/stdlib/libdoc/delegate/rdoc/index.html Delegate Lib] is another lib that provides delegation in Ruby.
Template metaprogramming(TMP) or Static Metaprogramming is a technique that allows the execution of programs at compile-time. It uses extremely early binding.
A primary requirement for a metaprogramming language is providing high-level abstractions to hide the internal representation of base programs.[http://lcgapp.cern.ch/project/architecture/ReflectionPaper.pdf] Each template language is specific for a base language and is generated from it. In this sense, a language of templates is a superset of the base language. Thus templates are abstractions that encapsulate a program pattern written by example.  This concept has been explained in detail in [http://pg-server.csc.ncsu.edu/mediawiki/index.php/CSC/ECE_517_Fall_2010/ch2_S24_rm#C.2B.2B_Template_Metaprogramming section 3.2.5]


Uses of template metaprogramming:
== Example of delegation in Ruby ==
* Compile-time dimensional analysis
Using Forwardable module provided in Ruby, this is how we would implement Robot example seen above [http://www.scribd.com/doc/27239260/Rails-Magazine-Issue-1-The-Beginning [5] ]:
* Multiple dispatch
* Design patterns
* Code optimization
* Lexing and parsing


== Packages ==
<pre>
require 'forwardable'
class Robot
  # Extending provides class methods
  extend Forwardable
  # Use of  def_delegators
  def_delegators :@arm,:package,:stack
  # Use of  def_delegator
  def_delegator :@heat_sensor, :measure ,:measure_heat
  def initialize
    @heat_sensor = HeatSensor.new
    @arm = RobotArm.new
  end
end
class HeatSensor
  #Celsius or Fahrenheit scale
  def measure(scale="c")
    t = rand(100)
    t = scale=="c" ? t : t * (9/5)
    puts "Heat is #{t}° #{scale.upcase}"
  end
end
class RobotArm
  def stack(boxes_number=1)
    puts "Stacking #{boxes_number} box(es)"
  end
  def package
    puts "Packaging"
  end
end
</pre>
<pre>
Using Single Forwardable module:


=== Javassist (Java Programming Assistant) ===
require "forwardable"
#using forwardable module
require "date"
#using data module
Date = Date.today # output will be <Date: 4909665/2,0,2299161>
# Preparing object for delegation
date.extend SingleForwardable #=> #<Date: 4909665/2,0,2299161>
# Adding delegation for Time.now
date.def_delegator :Time, "now","with_time"
puts date.with_time # will give output as Thu Jan 01 23:03:04 +0200 2009


Javassist is a Java library providing means to manipulate the Java bytecode of an application. It provides the support for structural reflection, i.e. the ability to change the implementation of a class at runtime. [http://www.csg.is.titech.ac.jp/~chiba/javassist/] Javassist is explicit metaprogramming, in which the metalanguage is Java. It is a load-time reflective system for Java which enables Java programs to define a new class at runtime and to modify a class file when the JVM loads it. Unlike other similar bytecode editors, Javassist provides two levels of API: source level and bytecode level.
</pre>
<pre>
Using delegate lib:


If the users use the source-level API, they can edit a class file without knowledge of the specifications of the Java bytecode. They do not have to even write an inserted bytecode sequence; Javassist instead can compile a fragment of source text on line (for example, just a single statement). This ease of use is a unique feature of Javassit against other tools. One can even specify inserted bytecode in the form of source text and Javassist compiles it on the fly. On the other hand, the bytecode-level API allows the users to directly edit a class file as other editors. Thus it makes Java bytecode manipulation simple.
require "delegate"
#using delegate module
require "date"
#using date module
# Notice the class definition
class CurrentDate < DelegateClass(Date)
  def initialize
    @date = Date.today
    # Pass the object to be delegated to the superclass.  
    super(@date)
  end
  def to_s
    @date.strftime "%Y/%m/%d"
  end
  def with_time
    Time.now
  end
end
cdate = CurrentDate.new #Notice how delegation works. Instead of doing cdate.date.day and defining attr_accessor for the date just do c.day
puts cdate.day #=>1
puts cdate.month #=>1
puts cdate.year #=>2009
puts cdate #=> 2009/01/01
puts cdate.with_time #=> Thu Jan 01 23:22:20 +0200 2009


Javassist has the following applications:
</pre>
* Aspect Oriented Programming:    Javassist can be a good tool for introducing new methods into a class and for inserting before/after/around advice at the both caller and callee sides.
* Reflection:    One of applications of Javassist is runtime reflection; Javassist enables Java programs to use a metaobject that controls method calls on base-level objects. No specialized compiler or virtual machine are needed.
* Remote method invocation:    Another application is remote method invocation. Javassist enables applets to call a method on a remote object running on the web server. Unlike the Java RMI, the programmer does notneed a stub compiler such as rmic; the stub code is dynamically produced by Javassist.


Example:
= Delegation in Java =
  BufferedInputStream fin = new BufferedInputStream(new FileInputStream("Point.class"));
Java supports delegation in the same way as other languages do. By using an instance of the class we would have otherwise inherited, and then forwarding messages to the instance we can do delegation in Java.[http://www.techartifact.com/blogs/2009/05/delegation-versus-inheritance-in-java.html [6]] e.g. We can associate a class with a thread in two ways:
  ClassFile cf = new ClassFile(new DataInputStream(fin));


A ClassFile object can be written back to a class file. write() in ClassFile writes the contents of the class file to a given DataOutputStream. ClassFile provides addField() and addMethod() for adding a field or a method (note that a constructor is regarded as a method at the bytecode level). It also provides addAttribute() for adding an attribute to the class file.
*By inheriting directly from class Thread.
*By implementing the Runnable interface and delegating to a Thread object.


To examine every bytecode instruction in a method body, CodeIterator is useful. A CodeIterator object allows you to visit every bytecode instruction one by one from the beginning to the end. To otbain this object, do as follows:


    ClassFile cf = ... ;
=== Examples of Delegation in Java ===
    MethodInfo minfo = cf.getMethod("move");    // we assume move is not overloaded.
Given below are the two examples of delegation, first being a simple one while the second being a complex example.
    CodeAttribute ca = minfo.getCodeAttribute();
    CodeIterator i = ca.iterator();


Other extensions are being developed to include reflective systems for C++ and Java e.g. OpenC++ and OpenJava which are extensible preprocessors based on compile-time reflection in C++ and Java respectively.
==== Simple Java Example ====


=== JRuby ===
In this example, the class C has method which does not perform itself and rather delegates to class A, the methods f() and g(). It seems that Class C is doing the work but in reality class A is doing it.[http://en.wikipedia.org/wiki/Delegation_pattern [6]]


JRuby is a complete implementation of Ruby in Java. The scripting and functional features of the Ruby language can be used by Java developers.[http://depth-first.com/articles/2006/10/24/metaprogramming-with-ruby-mapping-java-packages-onto-ruby-modules] Simple metaprogramming techniques can be  extended from Ruby so that Java packages are mapped onto to Ruby modules. This would be something like a Ruby-Java Bridge, since JRuby can be run from any platform with a JVM.
<pre>
//class A does the task of class C
class A {
  void f() { system.out.println("A: doing f()"); }
  void g() { system.out.println("A: doing g()"); }
  }


Example:
class C {
Using JRuby API calling JRuby from Java
  // class C delegates the method to class A
  A a = new A();
//delegated methods
  void f() { a.f(); }
  void g() { a.g(); }


    import org.jruby.*;
  // normal attributes
    public class SimpleJRubyCall {
  X x = new X();
    public static void main(String[] args) {
  void y() { /* do stuff */ }
        Ruby runtime = Ruby.getDefaultInstance();
}
    runtime.evalScript(“puts 1+2”);
      }
    }


With metaprogramming using JRuby one can
  void main() {
* add methods to class,
  C c = new C();
* add instance methods
*  add to have Java classes


Since metaprogramming empowers the programmer to create domain specific languages(DSL), the ones created by JRuby can always leverage Java libraries to build wrapper functionalities.
  c.f();
e.g. Simple JRuby DSL on top of HtmlUnit
  c.g();
}
</pre>


=== AspectJ ===
==== Complex Java Example ====
Another library worth mentioning here is AspectJ. It enforces the aspect oriented programming (AOP) approach in Java. Aspect oriented programming is a complimentary programming paradigm to object oriented programming and is used to improve the modularity of software systems. Thus, while object oriented programming is great for modeling common behavior on a hierarchy of objects, aspect oriented programming allows you to define cross-cutting concerns by adding direct semantics and can be applied across heterogeneous object models. [http://static.springsource.org/spring/docs/2.0.x/reference/aop.html] Applications of aspect oriented programming include logging, instrumenting and debugging.


In object oriented programs, the natural unit of modularity is the class. In AspectJ, aspects modularize concerns that affect more than one class. In addition to classes, aspect oriented programming uses 'aspects'. Aspects enable modularization of crosscutting concerns such as transaction management that cut across multiple types and objects. Thus, AspectJ package achieves metaprogramming features with more controllability.
By using interfaces, delegation can be made more flexible[ class-C need not refer to class-A or class-B, delegation is abstracted] and typesafe. Here, class C can delegate to either class A or class B. The implements clauses, improves type safety, since this ensures that each of the class must implements the methods in the interface. The main tradeoff being more code.
<pre>
interface I {
  void f();
  void g();
}


AspectJ introduces declaring aspects in the statically typed language Java by using 3 key concepts -
class A implements I {
* Join Points - well defined points in program execution
  void f() { system.out.println("A: doing f()"); }
* Advice - defines additional code to be executed around join points
  void g() { system.out.println("A: doing g()"); }
* Pointcut - define those points in the source code of a program where an advice will be applied
}


The core task of AspectJ's advice weaver is to statically transform a program so that at runtime it will behave according to the AspectJ language semantics. The AspectJ weaver takes class files as input and produces class files as output. The weaving process itself can take place at one of three different times: compile-time, post-compile time, and load-time. These two java files are 'woven' together by compiler i.e. the class and the aspect behavior are tied together. This is also known as 'plugging-in' the aspect. [http://oreilly.com/catalog/9780596006549]
class B implements I {
  void f() { system.out.println("B: doing f()"); }
  void g() { system.out.println("B: doing g()"); }
}


Example - Simple tracing/logging
class C implements I {
  // delegation
  I i = new A();


Consider the HelloWorld class below which implements an application that simply displays "Hello World!" on the standard output.
  void f() { i.f(); }
package helloworld;
  void g() { i.g(); }
class HelloWorld {
    public static void main(String[] args) {
            new HelloWorld().printMessage();
    }  
    void printMessage() {
            System.out.println("Hello world!");
    }
}


Consider another Java source file with an aspect definition as follows -
  // normal attributes
package helloworld;
  void toA() { i = new A(); }
aspect Trace of eachobject(instanceof(HelloWorld)) {
  void toB() { i = new B(); }
    pointcut printouts(): receptions(void printMessage());
    before(): printouts() {
              System.out.println("*** Entering printMessage ***");
    }
    after():  printouts() {
              System.out.println("*** Exiting printMessage ***");
    }
  }
  }


In above example, the Trace aspect injects tracing messages before and after method main of class HelloWorld. If one does not want tracing, one can simply leave the aspect out and plug it in as and when required.
void main() {
  C c = new C();


In contrast to reflection[low level], AspectJ provides more carefully controlled power, drawing on the rules learned from object-oriented development to encourage a clean and understandable program structure. An aspect imposes behavior on a class, rather than a class requesting behavior from an aspect. An aspect can modify a class without needing to edit that class - also known as 'reverse inheritance'.
  c.f();
  c.g();
}


=== MetaJ ===
</pre>


MetaJ is another package that supports metaprogramming in the Java language. A MetaJ program consists of the Java code with special metaprogramming declarations that will control how the output code is created. It uses templates and reflection. Templates are abstractions that encapsulate a program pattern written by example. Templates are translated to Java classes, so they can be accessed in the metaprogram. Accessing patterns by example inside ordinary Java programs is a major feature of MetaJ programming. [http://www.jucs.org/jucs_10_7/metaj_an_extensible_environment]
= Table of Comparison  =
{| class="wikitable sortable"  border="1" style="font-size: 100%; text-align: center; width: auto;"
|-
! '''Programming language'''
! '''Support for Delegation'''
! '''Syntax for implementing Delegation'''
|-
! '''[http://en.wikipedia.org/wiki/C%2B%2B C++]'''
| No in built support.Delegation has to be done manually.Time consuming
| Create a delegation link in delegator.
  class MyClass
  {
    FuBar fb; //delegation link
    void Fu() { fb.Fu(); } //
    void Bar() { bar.Bar(); }
  }
 


Language Dependency:
|-
MetaJ comprises of a set of concepts that are independent of the base language. These are syntax trees, code references, code iterators and code templates. A framework is defined which in which features common to most languages are abstracted. This supports independence from base language. Thus, generic operations can be defined and components that are language dependent can be plugged onto it.  
! '''[http://en.wikipedia.org/wiki/Perl_6 Perl 6]'''
| Yes via a pragma for delegating method calls to attributes of an object
| use delegation [http://dev.perl.org/perl6/rfc/193.html [8]]


Execution Flow Representation:
                attr1 => [qw( method1 method2 method3 )],
                attr2 => [qw( method4 method5 )],
                attr3 => __ALL__,
                attr4 => __ALL__,
                # etc
                ;
calls like:


[[Image:Meta_3.jpg]]
        $obj->method3(@args);
        $obj->method5(@other_args);
would act as if they were:


Example:
        $obj->{attr1}->method3(@args);
        $obj->{attr2}->method5(@other_args);


Template : SampleTempl
|-
! '''[http://en.wikipedia.org/wiki/Python_(programming_language) Python]'''
| Yes. Using Automatic Delegation (via __getattr__ and __setattr__) it can provide delegation with uses similar to inheritance without any limits and better control.[http://code.activestate.com/recipes/52295-automatic-delegation-as-an-alternative-to-inherita/ [10]]
| def __getattr__(self, attr): return getattr(self.file, attr)
  def __setattr__(self, attr, value): return setattr(self.file, attr, value)


package myTempl;
language = Java // base language plug­in
template #CompilationUnit SampleTempl{
#[#PackageDeclaration:pck]#
#[#ImportDeclarationList:imps]#
class SampleTempl { ... }
#TypeDeclaration:td
}


Instance of Template : Java Code
|-
! '''[http://en.wikipedia.org/wiki/Php PHP]'''
| Yes
| Class Delegator [http://rosettacode.org/wiki/Delegate [12]]
{
  function __construct() {$this->delegate = NULL ; }
  function operation() {
    if(method_exists($this->delegate, "thing"))
      return $this->delegate->thing() ;
    return 'default implementation' ;
  }
}
class Delegate {function thing() {return 'Delegate Implementation' ;}}
$a = new Delegator() ;
print "{$a->operation()}\n" ;
$a->delegate = 'A delegate may be any object' ;
print "{$a->operation()}\n" ;
$a->delegate = new Delegate() ;
print "{$a->operation()}\n" ;


package myTempl;
|-
import metaj.framework.AbstractTemplate;
! '''[http://en.wikipedia.org/wiki/Tcl Tcl]'''
public class SampleTempl extends AbstractTemplate{  
| Yes.Delegation-based model for Tk widgets.Included in Tcllib
  public final Reference imps, td, pck;
| //defining a delegate method [http://wiki.tcl.tk/11033 [10]]
  ... // Implementation of superclass abstract methods
Object instproc delegate {method obj} {
  my set delegate($method) $obj
  }
  Object instproc unknown {m args} {
  if {[my exists delegate($m)]} {
    eval [my set delegate($m)] $m $args
  } elseif {[my exists delegate(*)]} {
    eval [my set delegate(*)] $m $args
  }
  }
  }


Java SDK7 has added support for dynamic typing and metaprogramming and includes MetaJ implementation.
|-
! '''[http://en.wikipedia.org/wiki/Java_(programming_language) Java]'''
| Yes. Two ways.
| 1st way: Using an interface called Thingable to specify the type of delegates that respond to thing()
  2nd way: Use of traditional wrapper methods.[[http://www.techartifact.com/blogs/2009/05/delegation-versus-inheritance-in-java.html [6]]
|-
! '''[http://en.wikipedia.org/wiki/Objective_c Objective-C]'''
| Yes
| Delegating class has an outlet or property, usually one that is named delegate; if it is an outlet, it includes methods for setting and accessing the value of the outlet


=== C++ Template Metaprogramming ===
|-
! '''[http://en.wikipedia.org/wiki/Ruby_(programming_language) Ruby]'''
| Yes
| Wrapper method, delegate lib, forwardable module.


In C++, [http://pg-server.csc.ncsu.edu/mediawiki/index.php/CSC/ECE_517_Fall_2010/ch2_S24_rm#Template_Metaprogramming static metaprogramming] is implemented with the help of reflection. The most important implementation of reflection in C++ is using the feature of run time type-identification (RTTI) [http://depth-first.com/articles/2006/10/24/metaprogramming-with-ruby-mapping-java-packages-onto-ruby-modules]. RTTI is a system that keeps information about an object's data type in memory at run time. Run-time type information can apply to simple data types, such as integers and characters, or to generic objects. Enabling RTTI in C++ allows the use of dynamic_cast<> operation, the typeid operator or exceptions [http://en.wikipedia.org/wiki/Run-time_type_information].
|-
! '''[http://en.wikipedia.org/wiki/C_Sharp_(programming_language) C#]'''
| Yes.Delegate keyword is used to create a delegate and the type of a delegate is defined by the name of the delegate.
| //declaring a delegate named 'Del' that can encapsulate a method that takes a string as an argument and returns void
public delegate void Del(string message);[http://msdn.microsoft.com/en-us/library/ms173172.aspx [13]]
// Creating a method for a delegate.
public static void DelegateMethod(string message)
{
  System.Console.WriteLine(message);
}
// Instantiating the delegate.
Del handler = DelegateMethod;
// Calling the delegate.
handler("Hello World");


The template mechanism in C++ allows defining parametrized classes and functions. Templates together with other C++ features constitute a Turing-complete, compile-time sub- language of C++. A Turing-complete language is a language with at least a conditional and a looping construct. C++ can be considered to be a two-level language since a C++ program may contain both static code, which is evaluated at compile time, and dynamic code, which is executed at run time. Template meta-programs are the part of a C++ source that is executed during compilation. A meta-program can access information about types not generally available to ordinary programs [9].


Given below is an example of how to use templates for writing a common recursive factorial program:
|}
  template<int count>
  class FACTOR{
  public:
      enum {RESULT = count * FACTOR<count-1>::RESULT};
      };
  class FACTOR<1>{
  public:
      enum {RESULT = 1};
      };


If we write this-
<br />
  int j = FACTOR<5>::RESULT;


The above line will calculate the value of 5 factorial. As we instantiate FACTOR<5> the definition of this class depends on FACTOR<4>, which in turn depend on FACTOR<3> and so on. The compiler needs to create all these classes until the template specialization FACTOR<1> is reached. This means the entire recursion is done by the compiler during compile time and it uses the result as if it is a constant.
= Conclusion =


= Conclusion =
Thus delegation is a powerful design/reuse technique, and can be viewed as a relationship between objects where one object forwards certain method calls to another object, called its delegate. Delegation is simply passing a duty off to someone/something else.


Dynamically typed languages are best suited to provide support for metaprogramming due to their inherent nature of easily overcoming distinction between code and data e.g. Lisp provides this feature of interchangeability.  Code and data are both represented in Lisp as lists, so any list can easily be treated as either code or data.
Delegation pattern is better than inheritance in some ways and it is supported by many languages in various ways as shown in the table above. Delegation is useful to express relationship among classes, reducing coupling between classes, run-time flexibility – the delegate can be changed at run-time.  
It’s simple, therefore, to manipulate code as data, and then execute it – either via EVAL or by returning it as the result of a macro expansion. [3]
It has certain disadvantages too, such as, it is not directly supported by most popular object-oriented languages, also it doesn’t facilitate dynamic polymorphism.  


Thus, statically typed languages achieve metaprogramming using various techniques and tools to achieve the level of flexibility that dynamic languages provide immanently.
Hence the choice of using delegation depends on various factors such as programming language-support for multiple inheritance or design constraints requiring polymorphism.


= References and Notes =
= References and Notes =


*[1]  [http://portal.acm.org/citation.cfm?id=28718 Using prototypical objects to implement shared behavior in object-oriented systems]
[http://portal.acm.org/citation.cfm?id=28718]Using prototypical objects to implement shared behavior in OO systems,Henry Lieberman,November 1986
*[2]  [http://en.wikipedia.org/wiki/Object_composition#Aggregation]
 
*[3]  [http://en.wikipedia.org/wiki/Object_composition Object Composition]
[http://javalab.cs.uni-bonn.de/research/darwin/delegation.html]Darwin Project,October 2002
*[4]  [http://www.ccs.neu.edu/research/demeter/papers/context-journal/node3.html Issues Involved in Supporting Behavioral Evolution ]
 
*[5]  [http://www.developer.com/java/web/article.php/3504271/Java-Reflection-in-Action.htm Java Reflection in Action]
[http://rosettacode.org/wiki/Delegate] Delegation Examples, October 2002
*[6]  [http://www.developer.com/java/other/article.php/3556176/An-Introduction-to-Java-Annotations.htm An Introduction to Java Annotations]
 
*[7]  [http://en.wikipedia.org/wiki/Generic_programming Generic Programming]
[http://www.khelll.com/blog/ruby/delegation-in-ruby/] Delegation in Ruby,Khaled alHabache,April 2009
*[8]  [http://www.cs.tut.fi/~kk/webstuff/MetaProgrammingJavaKalvot.pdf Haapakorpi, M. ''Metaprogramming in Java'']
 
*[9]  [http://lcgapp.cern.ch/project/architecture/ReflectionPaper.pdf Attardi, G., Cisternino, A. ''Reflection support by means of template metaprogramming'']
[http://www.scribd.com/doc/27239260/Rails-Magazine-Issue-1-The-Beginning] Rails Magazine, October 2008
*[10] [http://www.csg.is.titech.ac.jp/~chiba/javassist/ Javassist]
 
*[11] [http://depth-first.com/articles/2006/10/24/metaprogramming-with-ruby-mapping-java-packages-onto-ruby-modules Metaprogramming with Ruby: Mapping Java Packages Onto Ruby Modules]
[http://www.techartifact.com/blogs/2009/05/delegation-versus-inheritance-in-java.html]Examples of delegation in Java,Vinay, May 2007
*[12] [http://static.springsource.org/spring/docs/2.0.x/reference/aop.html Aspect Oriented Programming with Spring]
 
*[13] [http://oreilly.com/catalog/9780596006549 Miles, R. 2004 ''AspectJ Cookbook'' O'Reilly Media]
[http://en.wikipedia.org/wiki/Delegation_pattern] Delegation pattern,Retrieved March 2006
*[14] [http://www.jucs.org/jucs_10_7/metaj_an_extensible_environment Oliveira, A.A., Braga, T.H, Maia, M.A., Bigonha and R.S. 2004. MetaJ: An Extensible Environment for Metaprogramming in Java, ''Journal of Universal Computer Science, vol. 10, no. 7 (2004), 872-891'']  
 
*[15] [http://depth-first.com/articles/2006/10/24/metaprogramming-with-ruby-mapping-java-packages-onto-ruby-modules Metaprogramming with Ruby: Mapping Java Packages Onto Ruby Modules ]
[http://dev.perl.org/perl6/rfc/193.pod]RFC 193,September 2000
*[16] [http://en.wikipedia.org/wiki/Run-time_type_information Run-time Type Information]
 
[http://wiki.tcl.tk/11033] Tcl example,Gustaf Neumann, October 2005
 
[http://code.activestate.com/recipes/52295-automatic-delegation-as-an-alternative-to-inherita/] Python delegation example,Alex Martelli,March 2001
 
[http://dev.perl.org/perl6/rfc/193.html] Perl delegation,Damian Conway, September 2007
 
[http://rosettacode.org/wiki/Delegate] PHP delegation,Retrieved January 2005
 
[http://msdn.microsoft.com/en-us/library/ms173172.aspx] C# delegation
 
[http://best-practice-software-engineering.ifs.tuwien.ac.at/patterns/delegation.html] Delegation Design Pattern,University of San Francisco,April 2010
 
[http://www.ccs.neu.edu/research/demeter/papers/context-journal/node3.html]Issues Involved in Supporting Behavioral Evolution,Karl,January 1997


= Further Reading =
= Further Reading =


*[http://www.cs.tut.fi/~kk/webstuff/MetaprogrammingCpp.pdf Metaprogramming in C++]
*[http://en.wikipedia.org/wiki/Delegation_pattern Delegation Pattern in detail]
*[http://en.wikipedia.org/wiki/Automatic_programming Automatic/Generative Programming]
*[http://www.khelll.com/blog/ruby/delegation-in-ruby/ Delegation in Ruby]
*[http://www.slideshare.net/dogangoko/new-features-of-java7-se-presentation News in the upcoming Java 7]
*[http://api.jquery.com/delegate/ Delegation in Jquery]
*[http://www.programmingvideotutorials.com/csharp/csharp-delegates C# delegates]
*[http://media.pragprog.com/titles/dscpq/delegates.pdf Cocoa programming]

Latest revision as of 23:14, 25 November 2010

Delegation-based programming languages

" I do not care how it is done, or who is it assigned to. If something is understood to be placed in the hands of another party, it is delegation " - 'Anonymous'

Introduction

Dictionary defines delegation as the assignment of authority and responsibility to another person to carry out specific activities. In simple words, it means "passing a duty off to someone or something else".

In programming context it is nothing different. It is basically entrusting an action to another agent. The term Delegation was initially introduced by Henry Lieberman in his 1986 paper "Using Prototypical Objects to Implement Shared Behavior in Object-Oriented Systems". [1] He defines delegation in object oriented languages as a programming language feature making use of the method lookup rules for dispatching so-called self-calls.

The above diagram depicts that a message receiver is asking another object (message holder) to do something on its behalf which may delegate it to someone and so on and so forth.[2]

Hence delegation means simply passing off a task to someone else so as to complete it on its behalf.


Delegation

Delegation is a simple yet, powerful concept of handing a task over to another part of the program. In object-oriented programming it is used to describe the situation wherein one object defers a task to another object, known as the delegate. Thus delegation is like inheritance done manually through object composition. Thus it refers to one object relying upon another to provide a specified set of functionalities.

Delegation, is also referred to as aggregation,consultation, or forwarding. In delegation one class may contain an instance of another class, and delegate some responsibility to that class. This is also referred to as the has-a relationship. Aggregation should not be confused with composition. Both aggregation and composition are used to describe one object containing another object, but composition implies ownership. Aggregation is more general and doesn't imply any responsibility for memory management. A class which contains other classes is called a composite class, while a class being contained is called a composited or composed class.

Delegation is a very powerful reuse technique. It provides run time flexibility. It is also called dynamic inheritance.

Delegation can be implemented in many programming languages like Ada, Aikido, C, C#, C++, Common Lisp, D, E, Go, J, Java, JavaScript, Logtalk, Objective-C,Oz, Perl,Perl 6, PHP, PicoLisp, Pop11, Python, Ruby, TCL, Vorpal[[3]

Example in a Java like language:

class Delegate
{
    void doSomething()
    {
        // "this" is also known as "current", "me" and "self" in other languages
        this.callMe()
    }
    void callMe() 
    {
        print("I am Delegate")
    }
}
class Delegator
{
    private Delegate d;  // delegationlink
    public Delegator(Delegate d)
    {
        this.d = d;
    }
    void doSomething() {
        d.doSomething() // call doSomething() on the Delegate instance
    }
    void callMe() {
        print("I am Delegator")
    }
}
d = new Delegate()
b = new Delegator(d) // establish delegation between two objects


Here calling b.doSomething() will result in "I am Delegate" being printed, since class Delegator "delegates" the method callMe() to a given object of class Delegate.

Delegation vs Inheritance

Inheritance :

  • Inheritance is restricted to compile time
  • Since it targets type rather than instances, it cannot be removed/changed at runtime
  • Inheritance can be statically type-checked

Delegation:

  • Delegation takes place at run-time
  • Since it takes place at run-time, it can even be removed at run-time
  • Cannot guarantee static type-safety (By using interfaces, delegation can be made more flexible and typesafe)


Hints to use Inheritance

  • Inheritance is used to create sub-categories of objects
  • Mostly identified in 'is-a' relationships between objects
  • Inheritance is used when two objects are of the same type but one of the objects may need to have its own customized functionality. The child object just inherits from the parent and writes its own implementation of the feature it needs extra.
  • Inheritance can be implemented on objects of the same type only.

Here we have an abstract base class. We extend this to to provide something that we can represent any product. We then provide a few specialisations for typical products like book,cd.This is a usual case when inheritance is used.

Hints to use Delegation

  • Delegation is used when two objects aren't of the same type but one has methods and attributes that the other wants to use internally instead of writing its own implementation
  • Identified as 'as-a' relationships where the type of included object may change during runtime.
  • Delegation is used when methods implementation needs to be handled by some other class within the parent tree. The class that will handle the method isn't known at compile time.
  • Code execution within objects needs to be determined dynamically.

In the above diagram, class C inherits from A. Also, class C has a method called as Call which simple calls the method Call from class B. Hence, class C is delegating its functionality to be implemented by Class B. For this, class C has an object reference to class B.[4]

Situations where you can use delegation

Consider following situation[4]:

  • Objective: We want a robot to have a heat sensor capability.
  • Initial design: So we initially decide to build a Robot class like the one shown below:

  • Problem with the design: Now all Robots should have a heat sensor. What if some robot did not have a heat sensor capability?
  • Solution: So we make a Robot base class and a VolcanoRobot class which inherits from Robot and performs the heat-sensor operations


  • Problem: But with this design whenever we want to modify anything related to the heat sensor, we will have to change the robot class. Also, with our design we have exposed heat sensor methods to Robot class.
  • Solution: Hence, in such situations delegation is best.

  • New design: Delegate the heat sensor functionality to Heat Sensor class. VolcanoRobot still has the 3 methods that are related to the sensor, but those are wrapper methods, they do nothing but to call the sensor corresponding ones, and that’s exactly what delegation is, just delegate functionality to the contained parts(delegates).

Delegation and composition go hand in hand to provide a flexible neat solution and also it serves the principle “separate changeable code from static one” . The price that one needs to pay for this is that we need wrapper methods, and extra time needed in processing because of the call of these wrapper methods.


Delegation Design Pattern

It is a design pattern in object oriented languages where an object expresses certain behavior to the outside but in reality delegates responsibility for implementing that behaviour to an associated object.

Consider the following examples in java:

class Subordinate  // the "delegate"
{  
    void performTask() 
    { 
      System.out.print("Subordinate is performing"); 
    }
}
class Manager // the "delegator"
{ 
    Subordinate slave = new Subordinate();  // create the delegate 
    void performTask() 
    { 
      slave.performTask(); // delegation
    } 
}
public class Main {
    // to the outside world it looks like Manager is actually doing work.
    public static void main(String[] args) {
        Manager boss = new Manager();
        boss.performTask();
    }
}

Delegation as a Language Feature

Prototype-based programming is a classless type of Object oriented programming technique which performs the work of inheritance in class-based languages. Delegation is the language feature that supports prototype-based programming. It is the mechanism by which code is selected for execution in a dynamic way. Delegation is the process by which a function or method, referred to in the context of one object, is found in another object. When a method is referred to by code defined for an object but is not itself found to be defined in the object the language runtime searches other objects, called delegates. Depending on the object model of the individual language the delegates may defined when the object is created or may be specified by the method-call syntax. The analogous process in a class-based language is dispatching to an inherited method, and an object's delegates perform the role of superclasses in a class-based language.

Delegation in Ruby

Delegation pattern in Ruby is implemented in 2 ways [5]:

1)Forwardable lib:Forwardable lib is a library that supports delegation. It has two modules

  • Forwardable
  • SingleForwardable:

Forwardable module:-

Using the methods def_delegator and def_delegators the Forwardable module provides delegation of specified methods to a designated object.

  • def_delegator(obj, method, alias = method) : Defines a method method which delegates to obj. If alias is provided, it is used as the name for the delegate method.
  • def_delegators(obj, *methods): Shortcut for defining multiple delegator methods, but with no provision for using a different name.

SingleForwardable module:-

Using the methods def_delegators, the SingleForwardable module provides delegation of specified methods to a designated object. This module is similar to Forwardable, but instead of their defining classes, it works on objects themselves.

2)Delegate lib:Delegate Lib is another lib that provides delegation in Ruby.

Example of delegation in Ruby

Using Forwardable module provided in Ruby, this is how we would implement Robot example seen above [5 ]:

require 'forwardable'
class Robot
  # Extending provides class methods
  extend Forwardable
  # Use of  def_delegators
  def_delegators :@arm,:package,:stack
  # Use of  def_delegator
  def_delegator :@heat_sensor, :measure ,:measure_heat
  def initialize
    @heat_sensor = HeatSensor.new
    @arm = RobotArm.new
  end
end
class HeatSensor
  #Celsius or Fahrenheit scale
  def measure(scale="c")
    t = rand(100)
    t = scale=="c" ? t : t * (9/5)
    puts "Heat is #{t}° #{scale.upcase}"
  end
end
class RobotArm
  def stack(boxes_number=1)
    puts "Stacking #{boxes_number} box(es)"
  end
  def package
    puts "Packaging"
  end
end
Using Single Forwardable module:

require "forwardable"
#using forwardable module
require "date"
#using data module
Date = Date.today # output will be <Date: 4909665/2,0,2299161>
 # Preparing object for delegation
date.extend SingleForwardable #=> #<Date: 4909665/2,0,2299161>
 # Adding delegation for Time.now
date.def_delegator :Time, "now","with_time"
puts date.with_time # will give output as Thu Jan 01 23:03:04 +0200 2009

Using delegate lib:

require "delegate"
#using delegate module
require "date"
#using date module
# Notice the class definition
class CurrentDate < DelegateClass(Date)
  def initialize
    @date = Date.today
    # Pass the object to be delegated to the superclass. 
    super(@date)
  end
 
  def to_s
    @date.strftime "%Y/%m/%d"
  end
 
  def with_time
    Time.now
  end
end
 
cdate = CurrentDate.new #Notice how delegation works. Instead of doing cdate.date.day and defining attr_accessor for the date just do c.day
puts cdate.day #=>1
puts cdate.month #=>1
puts cdate.year #=>2009 
puts cdate #=> 2009/01/01
puts cdate.with_time #=> Thu Jan 01 23:22:20 +0200 2009

Delegation in Java

Java supports delegation in the same way as other languages do. By using an instance of the class we would have otherwise inherited, and then forwarding messages to the instance we can do delegation in Java.[6] e.g. We can associate a class with a thread in two ways:

  • By inheriting directly from class Thread.
  • By implementing the Runnable interface and delegating to a Thread object.


Examples of Delegation in Java

Given below are the two examples of delegation, first being a simple one while the second being a complex example.

Simple Java Example

In this example, the class C has method which does not perform itself and rather delegates to class A, the methods f() and g(). It seems that Class C is doing the work but in reality class A is doing it.[6]

//class A does the task of class C
 class A {
   void f() { system.out.println("A: doing f()"); }
   void g() { system.out.println("A: doing g()"); }
 }

 class C {
   // class C delegates the method to class A
   A a = new A();
//delegated methods
   void f() { a.f(); }
   void g() { a.g(); }

   // normal attributes
   X x = new X();
   void y() { /* do stuff */ }
 }

 void main() {
   C c = new C();

   c.f();
   c.g();
 }

Complex Java Example

By using interfaces, delegation can be made more flexible[ class-C need not refer to class-A or class-B, delegation is abstracted] and typesafe. Here, class C can delegate to either class A or class B. The implements clauses, improves type safety, since this ensures that each of the class must implements the methods in the interface. The main tradeoff being more code.

interface I {
   void f();
   void g();
 }

 class A implements I {
   void f() { system.out.println("A: doing f()"); }
   void g() { system.out.println("A: doing g()"); }
 }

 class B implements I {
   void f() { system.out.println("B: doing f()"); }
   void g() { system.out.println("B: doing g()"); }
 }

 class C implements I {
   // delegation
   I i = new A();

   void f() { i.f(); }
   void g() { i.g(); }

   // normal attributes
   void toA() { i = new A(); }
   void toB() { i = new B(); }
 }

 void main() {
   C c = new C();

   c.f();
   c.g();
 }

Table of Comparison

Programming language Support for Delegation Syntax for implementing Delegation
C++ No in built support.Delegation has to be done manually.Time consuming Create a delegation link in delegator.
 class MyClass 
 {
   FuBar fb; //delegation link
   void Fu() { fb.Fu(); } //
   void Bar() { bar.Bar(); }
 }
 
Perl 6 Yes via a pragma for delegating method calls to attributes of an object use delegation [8]
               attr1 => [qw( method1 method2 method3 )],
               attr2 => [qw( method4 method5 )],
               attr3 => __ALL__,
               attr4 => __ALL__,
               # etc
               ;

calls like:

       $obj->method3(@args);
       $obj->method5(@other_args);

would act as if they were:

       $obj->{attr1}->method3(@args);
       $obj->{attr2}->method5(@other_args);
Python Yes. Using Automatic Delegation (via __getattr__ and __setattr__) it can provide delegation with uses similar to inheritance without any limits and better control.[10] def __getattr__(self, attr): return getattr(self.file, attr)
 def __setattr__(self, attr, value): return setattr(self.file, attr, value) 


PHP Yes Class Delegator [12]
{
 function __construct() {$this->delegate = NULL ; }
 function operation() {
   if(method_exists($this->delegate, "thing"))
     return $this->delegate->thing() ;
   return 'default implementation' ;
 }

} class Delegate {function thing() {return 'Delegate Implementation' ;}} $a = new Delegator() ; print "{$a->operation()}\n" ; $a->delegate = 'A delegate may be any object' ; print "{$a->operation()}\n" ; $a->delegate = new Delegate() ; print "{$a->operation()}\n" ;

Tcl Yes.Delegation-based model for Tk widgets.Included in Tcllib //defining a delegate method [10]

Object instproc delegate {method obj} {

  my set delegate($method) $obj
}
Object instproc unknown {m args} {
  if {[my exists delegate($m)]} {
    eval [my set delegate($m)] $m $args
  } elseif {[my exists delegate(*)]} {
    eval [my set delegate(*)] $m $args
  }
}
Java Yes. Two ways. 1st way: Using an interface called Thingable to specify the type of delegates that respond to thing()
 2nd way: Use of traditional wrapper methods.[[6]
Objective-C Yes Delegating class has an outlet or property, usually one that is named delegate; if it is an outlet, it includes methods for setting and accessing the value of the outlet
Ruby Yes Wrapper method, delegate lib, forwardable module.
C# Yes.Delegate keyword is used to create a delegate and the type of a delegate is defined by the name of the delegate. //declaring a delegate named 'Del' that can encapsulate a method that takes a string as an argument and returns void

public delegate void Del(string message);[13] // Creating a method for a delegate. public static void DelegateMethod(string message) {

  System.Console.WriteLine(message);

} // Instantiating the delegate. Del handler = DelegateMethod; // Calling the delegate. handler("Hello World");



Conclusion

Thus delegation is a powerful design/reuse technique, and can be viewed as a relationship between objects where one object forwards certain method calls to another object, called its delegate. Delegation is simply passing a duty off to someone/something else.

Delegation pattern is better than inheritance in some ways and it is supported by many languages in various ways as shown in the table above. Delegation is useful to express relationship among classes, reducing coupling between classes, run-time flexibility – the delegate can be changed at run-time. It has certain disadvantages too, such as, it is not directly supported by most popular object-oriented languages, also it doesn’t facilitate dynamic polymorphism.

Hence the choice of using delegation depends on various factors such as programming language-support for multiple inheritance or design constraints requiring polymorphism.

References and Notes

[1]Using prototypical objects to implement shared behavior in OO systems,Henry Lieberman,November 1986

[2]Darwin Project,October 2002

[3] Delegation Examples, October 2002

[4] Delegation in Ruby,Khaled alHabache,April 2009

[5] Rails Magazine, October 2008

[6]Examples of delegation in Java,Vinay, May 2007

[7] Delegation pattern,Retrieved March 2006

[8]RFC 193,September 2000

[9] Tcl example,Gustaf Neumann, October 2005

[10] Python delegation example,Alex Martelli,March 2001

[11] Perl delegation,Damian Conway, September 2007

[12] PHP delegation,Retrieved January 2005

[13] C# delegation

[14] Delegation Design Pattern,University of San Francisco,April 2010

[15]Issues Involved in Supporting Behavioral Evolution,Karl,January 1997

Further Reading