blob: 338ae98892d1419d18c342a0e44538788b236813 [file] [log] [blame]
Thoughts on delegation and type adapters:
-----------------------------------------
Assume the following scenario:
class A {
delegating B b;
void opA();
}
class B {
void opB();
}
class D {
void opD();
}
typeadapter C on D {
expose A::b;
void opA() { opD(); }
}
C tries to adapt D to A by saying that D's opD() can be called instead
of A's opA(), and by exposing the "b" end of A's association to
B. This association is designed as a delegating association, meaning
that B's features (in this example opB()) are transparently exposed by
A. In turn, if C is trying to adapt D to A, the user may hope that
exposing the end of this delegating association will also work as
delegating for D. In particular, it shall be possible with C in place
to do the following:
D d = ...;
d.opB();
This generally raises the question how the B instance for end "b" is
obtained during creation of A and---with C in place---for D. The
adapted D has to do this anyhow because the lower bound on the "b"
end is 1. But let's assume, that is worked out, e.g., by setting, at
some time, the B instance for the delegating instance:
B delegee = ...;
A a = ...;
a.b = delegee;
a.opB(); // --> invokes delegee.opB()
D d = ...;
d.b = delegee;
d.opB(); // --> invokes delegee.opB()
If the type adapter did not delegate to the exposed end, the adapter
would need to specify separate operations for those that make it
conform to the delegee's type (in this case B), and it would have to
implement them accordingly, as in
typeadapter C on D {
expose A::b;
void opA() { opD(); }
void opB() { b.opB(); }
}
This would give the flexibility to implement the features that A
obtained by delegation in a different way but at the same time
*requires* an implementation which otherwise would come "for free"
from the delegee.
For the time being it seems reasonable that at least by default a type
adapter delegates to an exposed end of a delegating association.