    |

|
White Papers -
Articles
|
|
"Creating
Synergistic Components with Delphi"
|
|
James Callan
- KOG Webzine (Page 4)
|
Linked Awareness
Link associations between classes increase
the relative independence of the classes. Thus, a link association should permit
a higher level of class independence than an equivalent aggregate association. To
better understand class independence, let's explore the creation of a simple custom
component. In particular, we will examine the technique by which custom components
expose event handlers to application programmers as a potential site for creating
link-based associations.
When you create a custom component and need to define your own event handler or override
inherited event handlers, you traditionally define a property to expose the event
for the component's clients (i.e., application programmers and other components).
Your component responds to the event in the default manner that you define. Additionally,
when you publish the event as a property, your component's clients can define additional
responses for the same event. In programming parlance, you have left a "hook"
or "callback" for the application programmer. Window's power derives from
callbacks such as these.
Application programmers using your custom component can use the property inspector
to define new behavior for events that you expose through the component's public
interface. Once a programmer uses the "hook" exposed by your component,
the event handler is usually unavailable for use elsewhere in the program unless
the programmer re-assigns the event handler dynamically. Since event dispatchers
are but mere method pointers, a simple assignment statement can be used
to re-assign event handlers during run-time. |
|
|
|
|
|
|
|
|
|
|
| unit MyButton; |
| interface |
| uses |
|
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs, StdCtrls; |
| type |
|
TMyButton = class(TButton) |
|
private |
|
|
FOnClick: TNotifyEvent; |
|
protected |
|
|
procedure Click; override; |
|
public |
|
published |
|
|
property OnClick: TNotifyEvent read
FOnClick write FOnClick; |
|
end; |
|
| procedure Register; |
|
| implementation |
|
| procedure TMyButton.Click; |
| begin |
|
Font.Style := [fsBold]; |
|
Caption := 'Click'; |
|
if Assigned(FOnClick) then FOnClick(self); |
| end; |
| procedure Register; |
| begin |
|
RegisterComponents('Informant', [TMyButton]); |
| end; |
| end. |
|
Figure
1
|
|
The listing in Figure 1 contains
a simple component inherited from TButton that overrides the standard TButton OnClick
event handler. The OnClick property exposes the FOnClick callback for the user (application
programmer). When the button receives the "Click" event Click is called,
which after changing the button’s font style to bold, it tests for the existence
of a user supplied event handler and optionally calls the user's routine. Later,
if the user wants the button to do something else when clicked, the user must either
perform special processing in the routine or dynamically re-assign the event handler
to another routine at run-time. Either way, the button's OnClick event is essentially
unavailable for re-use unless managed by the application programmer.
When the user overrides the button's
OnClick event, the user's program becomes a "client" and the button a "server."
The user's custom Click routine becomes tightly coupled to the button. When the user
becomes a client to the button, the button loses its independence. One click per
customer is the rule. The question arises, "Must a client necessarily cause
a loss of independence for its server?"
Imagine a component creation technique
wherein one component can make the same use of another component that a programmer
can, yet the components do not become tightly coupled. In such a situation both a
client component and the programmer could override a serving button's OnClick event,
or other events, without either interfering with the other. Many clicks per customer
becomes the rule. Link relationships between components permit this level of independence.
The utility that this independence yields remains veiled---hidden from developers
ensnared within the clutches of the aggregation paradigm. Come, let’s journey to
this hidden realm where ghosts and goblins abound.
|
 
|