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

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
 
(122 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. This term 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] 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. Thus delegation is like inheritance done manually through object composition.
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]]
[[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
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.
 
[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.


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]
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].
 
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]]


Example in a Java like language:
Example in a Java like language:
Line 56: Line 66:
== Delegation vs Inheritance ==
== Delegation vs Inheritance ==


Inheritance:
Inheritance :
* Inheritance is restricted to compile time
* [http://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming) Inheritance] is restricted to compile time
* Since it targets type rather than instances, it cannot be removed/changed at runtime
* Since it targets type rather than instances, it cannot be removed/changed at runtime
* Inheritance can be statically type-checked
* Inheritance can be statically type-checked
Line 75: Line 85:
[[ Image:Inheritance_db_newtable.gif ]]
[[ 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 by. We then provide a few specialisations for typical products like book,cd.This is a usual case when inheritance is used.
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
Hints to use Delegation
Line 85: Line 95:
[[ Image:Delegation.jpg ]]
[[ Image:Delegation.jpg ]]


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.
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]]


= Situations where you can use delegation =
= Situations where you can use delegation =


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


* Objective: We want a robot to have a heat sensor capability.  
* Objective: We want a robot to have a heat sensor capability.  
Line 141: Line 151:
     }
     }
  }
  }
have to write more stuff here. Examples from various programming lang.


== Delegation as a Language Feature ==
== 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.[http://en.wikipedia.org/wiki/Prototype-based_programming#Delegation]
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.


= Delegation in Ruby =
= Delegation in Ruby =


Delegation pattern in Ruby is implemented in 3 ways:
Delegation pattern in Ruby is implemented in 2 ways [http://www.scribd.com/doc/27239260/Rails-Magazine-Issue-1-The-Beginning [5]]:


1)'''Forwardable lib:'''[http://www.ruby-doc.org/stdlib/libdoc/forwardable/rdoc/index.html Forwardable lib] is a library that supports delegation, it has 2 modules Forwardable and SingleForwardable:
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
* SingleForwardable:


Forwardable module
Forwardable module:-


The Forwardable module provides delegation of specified methods to a designated object, using the methods def_delegator and def_delegators.
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_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.
Line 162: Line 172:
* def_delegators(obj, *methods): Shortcut for defining multiple delegator methods, but with no provision for using a different name.
* def_delegators(obj, *methods): Shortcut for defining multiple delegator methods, but with no provision for using a different name.


2)'''SingleForwardable module:''' The [http://www.ruby-doc.org/stdlib/libdoc/forwardable/rdoc/classes/SingleForwardable.html SingleForwardable] module provides delegation of specified methods to a designated object, using the methods def_delegators. This module is similar to Forwardable, but it works on objects themselves, instead of their defining classes.
SingleForwardable module:-


3)'''Delegate lib:'''[http://www.ruby-doc.org/stdlib/libdoc/delegate/rdoc/index.html Delegate Lib] is another lib that provides delegation in Ruby
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.
 
2)'''Delegate lib:'''[http://www.ruby-doc.org/stdlib/libdoc/delegate/rdoc/index.html Delegate Lib] is another lib that provides delegation in Ruby.


== Example of delegation in Ruby ==
== Example of delegation in Ruby ==
Using Forwardable module provided in Ruby, this is how we would implement Robot example seen above:
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] ]:


<pre>
<pre>
Line 204: Line 216:


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


</pre>
</pre>
Line 215: Line 231:


require "delegate"
require "delegate"
#using delegate module
require "date"
require "date"
#using date module
# Notice the class definition
# Notice the class definition
class CurrentDate < DelegateClass(Date)
class CurrentDate < DelegateClass(Date)
Line 233: Line 251:
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
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.day #=>1
puts cdate.month #=>1
puts cdate.month #=>1
puts cdate.year #=>2009 # Testing added methods like to_s
puts cdate.year #=>2009  
puts cdate #=> 2009/01/01
puts cdate #=> 2009/01/01
puts cdate.with_time #=> Thu Jan 01 23:22:20 +0200 2009
puts cdate.with_time #=> Thu Jan 01 23:22:20 +0200 2009
Line 243: Line 261:


= Delegation in Java =
= 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.[http://www.techartifact.com/blogs/2009/05/delegation-versus-inheritance-in-java.html] e.g. We can associate a class with a thread in two ways:
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:


*By inheriting directly from class Thread.
*By inheriting directly from class Thread.
Line 254: Line 272:
==== Simple Java 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.[http://en.wikipedia.org/wiki/Delegation_pattern]
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]]


<pre>
<pre>
//class A does the task of class C
  class A {
  class A {
   void f() { system.out.println("A: doing f()"); }
   void f() { system.out.println("A: doing f()"); }
Line 263: Line 282:


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


= Table of Comparison  =
= Table of Comparison  =
==Cross platform comparison==
{| class="wikitable sortable"  border="1" style="font-size: 100%; text-align: center; width: auto;"
{| class="wikitable sortable"  border="1" style="font-size: 100%; text-align: center; width: auto;"
|-
|-
! '''GUI Toolkit'''
! '''Programming language'''
! '''Microsoft Windows|Windows'''
! '''Support for Delegation'''
! '''Linux'''
! '''Syntax for implementing Delegation'''
! '''Mac OS X'''
|-
|-
! '''Tk'''
! '''[http://en.wikipedia.org/wiki/C%2B%2B C++]'''
| yes
| No in built support.Delegation has to be done manually.Time consuming
| yes
| Create a delegation link in delegator.
| yes
  class MyClass
  {
    FuBar fb; //delegation link
    void Fu() { fb.Fu(); } //
    void Bar() { bar.Bar(); }
  }
 
 
|-
|-
! '''FxRuby'''
! '''[http://en.wikipedia.org/wiki/Perl_6 Perl 6]'''
| yes
| Yes via a pragma for delegating method calls to attributes of an object
| yes
| use delegation [http://dev.perl.org/perl6/rfc/193.html [8]]
| yes
 
                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);
 
|-
|-
! '''WxRuby'''
! '''[http://en.wikipedia.org/wiki/Python_(programming_language) Python]'''
| yes
| 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]]
| yes
| def __getattr__(self, attr): return getattr(self.file, attr)
| yes
  def __setattr__(self, attr, value): return setattr(self.file, attr, value)
 
 
|-
|-
! '''QtRuby'''
! '''[http://en.wikipedia.org/wiki/Php PHP]'''
| yes
| Yes
| yes
| Class Delegator [http://rosettacode.org/wiki/Delegate [12]]
| yes
{
  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" ;
 
|-
|-
! '''Shoes'''
! '''[http://en.wikipedia.org/wiki/Tcl Tcl]'''
| yes
| Yes.Delegation-based model for Tk widgets.Included in Tcllib
| yes
| //defining a delegate method [http://wiki.tcl.tk/11033 [10]]
| yes
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
  }
}
 
|-
|-
! '''Swing'''
! '''[http://en.wikipedia.org/wiki/Java_(programming_language) Java]'''
| yes
| Yes. Two ways.
| yes
| 1st way: Using an interface called Thingable to specify the type of delegates that respond to thing()
| yes
  2nd way: Use of traditional wrapper methods.[[http://www.techartifact.com/blogs/2009/05/delegation-versus-inheritance-in-java.html [6]]
|-
|-
! '''Monkeybars'''
! '''[http://en.wikipedia.org/wiki/Objective_c Objective-C]'''
| yes
| Yes
| 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
| yes
 
|-
|-
! '''Cocoa'''
! '''[http://en.wikipedia.org/wiki/Ruby_(programming_language) Ruby]'''
| No
| Yes
| No
| Wrapper method, delegate lib, forwardable module.
| yes
 
|-
|-
! '''GTK'''
! '''[http://en.wikipedia.org/wiki/C_Sharp_(programming_language) C#]'''
| yes
| Yes.Delegate keyword is used to create a delegate and the type of a delegate is defined by the name of the delegate.
| yes
| //declaring a delegate named 'Del' that can encapsulate a method that takes a string as an argument and returns void
| yes
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");
 
 
|}
|}


Line 381: Line 458:


= Conclusion =
= Conclusion =
Delegation is simply passing a duty off to someone/something else
 
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 =
= 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 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://rosettacode.org/wiki/Delegate Delegates]
[http://rosettacode.org/wiki/Delegate] Delegation Examples, October 2002
*[6]  [http://javalab.cs.uni-bonn.de/research/darwin/delegation.html Darwin Project]
 
*[7]  [http://en.wikipedia.org/wiki/Prototype-based_programming#Delegation Delegation as a Language Feature]
[http://www.khelll.com/blog/ruby/delegation-in-ruby/] Delegation in Ruby,Khaled alHabache,April 2009
*[8] [http://www.khelll.com/blog/ruby/delegation-in-ruby/ Delegation in Ruby]
 
*[9]  [http://best-practice-software-engineering.ifs.tuwien.ac.at/patterns/delegation.html Delegation Design Pattern]
[http://www.scribd.com/doc/27239260/Rails-Magazine-Issue-1-The-Beginning] Rails Magazine, October 2008
*[10]  [http://en.wikipedia.org/wiki/Delegation_pattern Delegation in Java]
 
*[11] [http://www.techartifact.com/blogs/2009/05/delegation-versus-inheritance-in-java.html Examples of delegation in Java]
[http://www.techartifact.com/blogs/2009/05/delegation-versus-inheritance-in-java.html]Examples of delegation in Java,Vinay, May 2007
 
[http://en.wikipedia.org/wiki/Delegation_pattern] Delegation pattern,Retrieved March 2006
 
[http://dev.perl.org/perl6/rfc/193.pod]RFC 193,September 2000
 
[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 =
Line 402: Line 502:
*[http://en.wikipedia.org/wiki/Delegation_pattern Delegation Pattern in detail]
*[http://en.wikipedia.org/wiki/Delegation_pattern Delegation Pattern in detail]
*[http://www.khelll.com/blog/ruby/delegation-in-ruby/ Delegation in Ruby]
*[http://www.khelll.com/blog/ruby/delegation-in-ruby/ Delegation in Ruby]
*[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