Delegation pattern
Encyclopedia
In software engineering
Software engineering
Software Engineering is the application of a systematic, disciplined, quantifiable approach to the development, operation, and maintenance of software, and the study of these approaches; that is, the application of engineering to software...

, the delegation pattern is a design pattern
Design pattern
A design pattern in architecture and computer science is a formal way of documenting a solution to a design problem in a particular field of expertise. The idea was introduced by the architect Christopher Alexander in the field of architecture and has been adapted for various other disciplines,...

 in object-oriented programming
Object-oriented programming
Object-oriented programming is a programming paradigm using "objects" – data structures consisting of data fields and methods together with their interactions – to design applications and computer programs. Programming techniques may include features such as data abstraction,...

 where an object
Object (computer science)
In computer science, an object is any entity that can be manipulated by the commands of a programming language, such as a value, variable, function, or data structure...

, instead of performing one of its stated tasks, delegates that task to an associated helper object. There is an Inversion of Responsibility in which a helper object, known as a delegate, is given the responsibility to execute a task for the delegator. The delegation pattern is one of the fundamental abstraction
Abstraction (computer science)
In computer science, abstraction is the process by which data and programs are defined with a representation similar to its pictorial meaning as rooted in the more complex realm of human life and language with their higher need of summarization and categorization , while hiding away the...

 patterns that underlie other software patterns such as composition
Object composition
In computer science, object composition is a way to combine simple objects or data types into more complex ones...

 (also referred to as aggregation), mixin
Mixin
In object-oriented programming languages, a mixin is a class that provides a certain functionality to be inherited or just reused by a subclass, while not meant for instantiation , Mixins are synonymous functionally with abstract base classes...

s and aspect
Aspect (computer science)
In computer science, an aspect of a program is a feature linked to many other parts of the program, but which is not related to the program's primary function. An aspect crosscuts the program's core concerns, therefore violating its separation of concerns that tries to encapsulate unrelated functions...

s.

Simple

In this Java
Java (programming language)
Java is a programming language originally developed by James Gosling at Sun Microsystems and released in 1995 as a core component of Sun Microsystems' Java platform. The language derives much of its syntax from C and C++ but has a simpler object model and fewer low-level facilities...

 example, the class
Class (computer science)
In object-oriented programming, a class is a construct that is used as a blueprint to create instances of itself – referred to as class instances, class objects, instance objects or simply objects. A class defines constituent members which enable these class instances to have state and behavior...

 has a method. This print method, rather than performing the print itself, delegates to class . To the outside world it appears that the class is doing the print, but class is the one actually doing the work.

Delegation is simply passing a duty off to someone/something else. Here is a simple example:


class RealPrinter { // the "delegate"
void print {
System.out.print("something");
}
}

class Printer { // the "delegator"
RealPrinter p = new RealPrinter; // create the delegate
void print {
p.print; // delegation
}
}

public class Main {
// to the outside world it looks like Printer actually prints.
public static void main(String[] args) {
Printer printer = new Printer;
printer.print;
}
}

Complex

By using interfaces
Interface (Java)
An interface in the Java programming language is an abstract type that is used to specify an interface that classes must implement. Interfaces are declared using the interface keyword, and may only contain method signature and constant declarations...

, delegation can be made more flexible and typesafe. "Flexibility" here means that need not refer to or in any way, as the switching of delegation is abstracted from . Needless to say, and don't count as references to and . In this example, class can delegate to either class or class . Class has methods to switch between classes and . Including the clauses improves type safety
Type safety
In computer science, type safety is the extent to which a programming language discourages or prevents type errors. A type error is erroneous or undesirable program behaviour caused by a discrepancy between differing data types...

, because each class must implement the methods in the interface. The main tradeoff is more code.


interface I {
void f;
void g;
}

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

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

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

public void f { i.f; }
public void g { i.g; }

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

public class Main {
public static void main(String[] args) {
C c = new C;
c.f; // output: A: doing f
c.g; // output: A: doing g
c.toB;
c.f; // output: B: doing f
c.g; // output: B: doing g
}
}

C# example

This is a C# example of the complex Java example above.


public interface I
{
void F;
void G;
}

public class A : I
{
public void F { System.Console.WriteLine("A: doing F"); }
public void G { System.Console.WriteLine("A: doing G"); }
}

public class B : I
{
public void F { System.Console.WriteLine("B: doing F"); }
public void G { System.Console.WriteLine("B: doing G"); }
}

public class C : I
{
// delegation
I i = new A;

public void F { i.F; }
public void G { i.G; }

// normal attributes
public void ToA { i = new A; }
public void ToB { i = new B; }
}

public class Program
{
public static void Main
{
C c = new C;
c.F; // output: A: doing F
c.G; // output: A: doing G
c.ToB;
c.F; // output: B: doing F
c.G; // output: B: doing G
}
}

C++ example (complex)

This example is a C++
C++
C++ is a statically typed, free-form, multi-paradigm, compiled, general-purpose programming language. It is regarded as an intermediate-level language, as it comprises a combination of both high-level and low-level language features. It was developed by Bjarne Stroustrup starting in 1979 at Bell...

 version of the complex Java example above. Since C++ does not have an interface construct, a pure virtual class plays the same role. The advantages and disadvantages are largely the same as in the Java example.


  1. include

using namespace std;

class I {
public:
virtual void f = 0;
virtual void g = 0;
virtual ~I {}
};

class A : public I {
public:
void f { cout << "A: doing f" << endl; }
void g { cout << "A: doing g" << endl; }
~A { cout << "A: cleaning up." << endl; }
};

class B : public I {
public:
void f { cout << "B: doing f" << endl; }
void g { cout << "B: doing g" << endl; }
~B { cout << "B: cleaning up." << endl; }
};

class C : public I {
public:
// construction/destruction
C : i( new A ) { }
virtual ~C { delete i; }

private:
// delegation
I* i;

public:
void f { i->f; }
void g { i->g; }

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

int main {
// we use by default the instance of A.
C c;
// Here we are calling A methods.
c.f;
c.g;
// Here delete the instance of A and switch with the instance of B.
c.toB;
// Now with the same methods we are calling B methods.
c.f;
c.g;

// The delegate is deleted by normal C++ scoping rules.
}


The output:

A: doing f
A: doing g
A: cleaning up.
B: doing f
B: doing g
B: cleaning up.

Eiffel example (complex)

This example is a Eiffel
Eiffel
-Engineering:* Eiffel Tower in Paris, designed by Gustave Eiffel in motif as twin to the Eifel ridge, re-dubbed Maria Pia Bridge, previously built in o Porto, Portugal - The Twin Towers of Eiffel...

 version of the complex Java example above.


deferred class I feature
f is deferred end
g is deferred end
end

class A inherit I feature
f is do print("A: doing f%N") end
g is do print("A: doing g%N") end
end

class B inherit I feature
f is do print("B: doing f%N") end
g is do print("B: doing g%N") end
end

class C inherit I creation to_a, to_b feature
i: I

f is do i.f end
g is do i.g end

to_a is do create {A} i end
to_b is do create {B} i end
end

class MAIN creation main feature
main is local c: C do
create c.to_a
c.f
c.g
c.to_b
c.f
c.g
end
end

Objective-C example

Delegation is very common in the Cocoa
Cocoa (API)
Cocoa is Apple's native object-oriented application programming interface for the Mac OS X operating system and—along with the Cocoa Touch extension for gesture recognition and animation—for applications for the iOS operating system, used on Apple devices such as the iPhone, the iPod Touch, and...

 framework. The following example is an Objective-C version of the complex Java example above.



@protocol I
-(void) f;
-(void) g;
@end

@interface A : NSObject { }
@end
@implementation A
-(void) f { NSLog(@"A: doing f"); }
-(void) g { NSLog(@"A: doing g"); }
@end

@interface B : NSObject { }
@end
@implementation B
-(void) f { NSLog(@"B: doing f"); }
-(void) g { NSLog(@"B: doing g"); }
@end

@interface C : NSObject {
id i; // delegation
}
-(void) toA;
-(void) toB;
@end

@implementation C
-(void) f { [i f]; }
-(void) g { [i g]; }

-(void) toA { [i release]; i =  alloc] init]; }
-(void) toB { [i release]; i =  alloc] init]; }

// constructor
-(id)init {
if (self = [super init]) { i =  alloc] init]; }
return self;
}

// destructor
-(void)dealloc { [i release]; [super dealloc]; }
@end

int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = SAutoreleasePool alloc] init];
C *c =  alloc] init];
[c f]; // output: A: doing f
[c g]; // output: A: doing g
[c toB];
[c f]; // output: B: doing f
[c g]; // output: B: doing g
[c release];
[pool drain];
return 0;
}

Perl


use strict;
use warnings;
use 5.010_000;

package Example::Printer::Delegate::Role;
use Moose::Role;
cut

package Example::Printer::Delegate::A;
use Moose;
with 'Example::Printer::Delegate::Role';

sub print_string {
say 'Printed from A';
}

package Example::Printer::Delegate::B;
use Moose;
with 'Example::Printer::Delegate::Role';

sub print_string {
say 'Printed from B';
}

sub greet {
say 'And a hello to you!';
}

package Example::Printer;
use Moose;

has delegate => (
is => 'rw',
does => 'Example::Printer::Delegate::Role',
predicate => 'hasDelegate'
);

sub print {
my $self = shift;

# Check to see, if I have a delegate
if ( $self->hasDelegate ) {
my $delegate = $self->delegate;

# Call the delegate's print method. The role assures me that
# print_string exists.
$delegate->print_string;

# Let's check to see if the delegate supports the greet method.
if ( $delegate->can('greet') ) {
# It does so, let's also greet people!
$delegate->greet;
}
}
else {
warn 'No delegate!';
}
}

package main;
use strict;

my $delegateA = Example::Printer::Delegate::A->new;
my $delegateB = Example::Printer::Delegate::B->new;
my $printer = Example::Printer->new;

$printer->print; # Will get a warning about not having a delegate.

say 'Setting delegate to Delegate A';
$printer->delegate($delegateA);
$printer->print; # This will call $a's print_string method.

say 'Setting delegate to Delegate B';
$printer->delegate($delegateB);
$printer->print; # This will call $b's print_string, and greet methods.

Python Example (complex)


class I:
def f(self): pass
def g(self): pass

class A(I):
def f(self):
print "A: doing f"

def g(self):
print "A: doing g"

class B(I):
def f(self):
print "B: doing f"

def g(self):
print "B: doing g"

class C(I):
def __init__(self):
# delegation
self.i = A

def f(self):
self.i.f

def g(self):
self.i.g

# normal attributes
def to_a(self):
self.i = A

def to_b(self):
self.i = B

if __name__ '__main__':
c = C
c.f # output: A: doing f
c.g # output: A: doing g
c.to_b
c.f # output: B: doing f
c.g # output: B: doing g

Ruby on Rails example (complex)


module I
def f
puts "#{self.class}: doing f"
end

def g
puts "#{self.class}: doing g"
end
end
class A
include I
end
class B
include I
end
class C
attr_accessor :i
delegate :f, :g, :to => :i

def initialize(klass = A)
self.i = klass.new
end
end
c = C.new
c.f # output: A: doing f
c.g # output: A: doing g
c = C.new(B)
c.f # output: B: doing f
c.g # output: B: doing g


Tcl

  1. TclOO is part of Tcl in 8.6 addon package in 8.5

if { [ catch {package require TclOO } err ] != 0 } {
puts stderr "Unable to find package TclOO ... adjust your auto_path!";
}

oo::class create I {
constructor {} {
}

method f { } {puts "Error please implement"; };
method g { } {puts "Error please implement"; };
}

oo::class create A {
superclass I

constructor {} {
next;
}

method f { } {
puts "A : doing f"
}

method g { } {
puts "A : doing g"
}
}

oo::class create B {
superclass I

constructor {} {
next;
}

method f { } {
puts "B : doing f"
}

method g { } {
puts "B : doing g"
}
}

oo::class create C {
variable i

constructor {} {
# delegation
set i [A new ]
}

method f { } {
$i f
}

method g { } {
$i g
}

# normal attributes
method to_a { } {
$i destroy;
set i [A new ]
}

method to_b { } {
$i destroy;
set i [B new ]
}
}

set c [C new ]
$c to_a
$c f ; # output A : doing f
$c g ; # output A : doing g
$c to_b
$c f ; # output B : doing f
$c g ; # output B : doing g

PHP



// Interface for printers.
interface iPrinter {

// 'print' is a reserved word.
public function printIt($subject);
}

// LinePrinter Printer Delegate
class LinePrinter implements iPrinter {

public function printIt($line) {

print $line;
print "\n";
}
}

// ArrayPrinter Printer Delegate
class ArrayPrinter implements iPrinter {

public function printIt($array) {

if ( ! is_array($array)) {
throw new Exception ('Expected Array');
}

print_r($array);
}
}

// Custom object.
class MyObject {

protected $printer;

public function __construct {

// Set delegate.
$this->printer = new LinePrinter;
}

public function printData {

$this->printer->printIt('Some string data');
}
}

// Another custom object
class MyOtherObject {

protected $printer;

public function __construct {

// Set delegate.
$this->printer = new ArrayPrinter;
}

public function printData {

$this->printer->printIt(array(1,2,3));
}
}

// ...

// Run it.
$object = new MyObject;
$object->printData;

// Run it.
$object = new MyOtherObject;
$object->printData;

See also

  • Delegation (programming)
    Delegation (programming)
    In object-oriented programming, there are two related notions of delegation.* Most commonly, it refers to a programming language feature making use of the method lookup rules for dispatching so-called self-calls as defined by Lieberman in his 1986 paper "Using Prototypical Objects to Implement...

  • Design pattern
    Design pattern (computer science)
    In software engineering, a design pattern is a general reusable solution to a commonly occurring problem within a given context in software design. A design pattern is not a finished design that can be transformed directly into code. It is a description or template for how to solve a problem that...

  • Post-object programming

External links
  • Delegation on Rosetta Code
    Rosetta Code
    Rosetta Code is a wiki-based programming chrestomathy website with solutions to various programming problems in many different programming languages. It was created in 2007 by Mike Mol. Rosetta Code includes 450 programming tasks, and covers 351 programming languages...

The source of this article is wikipedia, the free encyclopedia.  The text of this article is licensed under the GFDL.
 
x
OK