Delegate Events vs.
Adapter Events
the events to the Receiver becomes nothing more than pointing the Delegate to the address of the
Receiver's method.
• Fourth, a lot less code is required to implement Delegates.
In addition, Delegates tolerate unhandled eventswhich is a common occurrence better than interfaces, because
they wrap a single method. In an interface event−based system, a message is still sent to an interface that
impacts the receiver, even if the event is unhandled. While Delegates also set messages in motion, the speed
and size penalty for the unhandled events is much less than it would be for sending a call to an interface.
To handle even one event, the Receiver must still implement the entire event− interface, and the Sender must
still raise all of the events in an event interface, whether or not the Receiver has been equipped to handle
them. Delegates can't bind method calls if there are no methods in the Receiver to bind; thus, the case of the
missing event handler is not possible in a Delegate event model. Even if a method is not implemented in the
Receiver, there is still zero cost or impact upon the Receiver, because no adapter needs to be resident.
The Delegate event model and the delegation model are easier to implement, because it's easier to discover
the facilities of Receiver objects and their inclination to handle events. And, most important, Receiver
implementors, the programmers, need no extra effort and code in order to offer their classes and objects for
event handling. A receiver also requires no special action to register listener status with the construct that
marshals the event−handler calls, such as aggregation in an Adaptee class. Delegates register listener
interests implicitly in the method reference itself.
In this regard, Delegates are able to intrinsically support multicast scenarios. Creating and managing multicast
events requires little more than the combination of Delegate references, as described earlier. The same task in
interface−based event systems is difficult, time−consuming, and error−prone. In short, Delegates make
event−wiring easy.
However, the Interface/Adapter event model has some advantages over the Delegates, not only for events but
to support general Adapter pattern algorithms. The following arguments against Delegates have been offered
up by the anti−Delegate community ever since they were introduced in Visual J++:
• Bound−method references add complexity to the type system. This is not really a complexity cost for
the programmer but more of a concern for the type− system architects. However, the bound−method
call wrap in the Delegate construct is a special case in what is otherwise a pure object−oriented
framework, in which classes do everything and are everything. A Delegate is thus a new type that
needs special treatment by the type system.
• While Delegates are technically classes, the semantics and language needed to implement them is
cryptic and complex, even though less code is required in comparison to Adapter−interface
construction. While interface bridging and interface−member referencing are more difficult than
simple object−member referencing, it is still easier to construct the interface reference code than the
Delegate reference code.
• Delegates are not very expressive and do nothing else but reference a method call. They cannot
implement groups of operations or contain state or be expanded in any way. In many respects, they
are nothing but function pointers, which are undesirable in an OO framework.
The argument against Delegates is that the reference to a single method can just as easily be provided in a
more simple fashion using a single member Adapter object. Adapters obviously require additional code and
some incorporation into the Receiver code. As an example of the Adapter interface model, you can compare
sorting with Adapters pattern as I did with the Delegates earlier in this chapter.
491