Supponi quanto segue:
class Foo {
public function foo1() {...}
public function foo2() {...}
}
class Bar {
public function bar1() {...}
public function bar2() {...}
}
Classicamente, quando si compone una classe di questi due, che delega le chiamate, sembrerebbe:
class FooBar {
var foo:Foo;
var bar:Bar;
public function foo1() { foo.foo1(); }
public function foo2() { foo.foo2(); }
public function bar1() { bar.bar1(); }
public function bar2() { bar.bar2(); }
}
Non esiste un costrutto sintattico per supportare ciò che stai facendo. Per ogni chiamata che desideri delegare, dovrai scrivere la stessa cosa più e più volte.
Le lingue che utilizzano il passaggio di messaggi, come Ruby, Smalltalk e Objective-C, risolvono il problema, richiamando un metodo specifico in risposta a messaggi sconosciuti.
Sembra qualcosa del tipo:
class FooBar {
var foo:Foo;
var bar:Bar;
override public function handleUnknownMethod(name:String, args:Array) {
if (foo.hasMethod(name)) foo.invoke(name, args);
else if (bar.hasMethod(name)) bar.invoke(name, args);
else super.handleUnknowMethod(name, args);
}
}
Questo è "migliore" nel senso che non devi farlo per ogni singolo metodo. Ciò rende la composizione meno costosa e la condivisione del codice più semplice.
Si noti che anche questa non è una delegazione sintattica. Ciò che è, è il rinvio della gestione delle chiamate a metodi non definiti in runtime, il che significa che è possibile utilizzare il linguaggio stesso per gestirli.
La delega sintattica sarebbe qualcosa come:
class FooBar {
@forwardAll var foo:Foo;
@forwardAll var bar:Bar;
}
Sarebbe uno zucchero sintattico che il compilatore risolverebbe generando un metodo pubblico per ogni metodo pubblico in Foo
, che delegherebbe semplicemente la chiamata a foo
e farebbe lo stesso per bar
/ Bar
.