Example 8.2 Chaining through an intermediate object
To use chaining for this application, we create an intermediate class, TMuseumCount, that has the three TCounter objects as public data items. The client class (the user interface) then updates the counts through the TMuseumCount object.Ex 8.2 step 1 Defining the intermediate object
The TCounter class remains as before. Well create the TMuseumCount class in a separate unit. Add another unit to the project from example 8.1, save it as MuseumCountU.pas, and edit it as follows:unit MuseumCountU;TMuseumCount is a very simple class. It is derived from TObject and contains three public data items of type TCounter. (Thats why we need the uses CounterU clause). TMuseumCount contains only one method, a constructor extending the inherited constructor to create the associated TCounter objects (lines 1719). So whenever an object of type TMuseumCount is created it automatically creates the necessary TCounter objects.
// using chaining
interface
uses CounterU;
type
TMuseumCount = class(TObject)
public
VEntered, VInside, VLeft: TCounter;
constructor Create;
end;
implementation
{ TMuseumCount }
constructor TMuseumCount.Create;
begin
// propagate construction
inherited Create;
VEntered := TCounter.Create;
VInside := TCounter.Create;
VLeft := TCounter.Create;
end;
end.
Ex 8.2 step 2 Using chaining
We now modify the user interface class, TfrmAttendance, to use the intermediate class TMuseumCount instead of the individual TCounter objects:unit UpAndDownU;We replace TfrmAttendances three private TCounter objects by a single TMuseumCount object and so we substitute MuseumCountU for CounterU in the uses clause. We also change the forms OnCreate event handler to create a single TMuseumCount object in the place of the three TCounter objects.
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls, Spin, MuseumCountU;
type
TfrmAttendance = class(TForm)
...
private
MuseumCount: TMuseumCount;
end;
var
frmAttendance: TfrmAttendance;
implementation
{$R *.dfm}
procedure TfrmAttendance.btnEnterClick(Sender: TObject) ;
begin
MuseumCount.VEntered.Add (sedEnter.Value) ;
lblIn.Caption := IntToStr(MuseumCount.VEntered.Total) ;
MuseumCount.VInside.Add (sedEnter.Value) ;
lblVisitors.Caption := IntToStr(MuseumCount.VInside.Total) ;
sedEnter.Value := 0;
end;
procedure TfrmAttendance.btnLeaveClick(Sender: TObject) ;
begin
with MuseumCount do
begin
VLeft.Add (sedLeave.Value) ;
lblOut.Caption := IntToStr(VLeft.Total) ;
VInside.Subtract (sedLeave.Value) ;
lblVisitors.Caption := IntToStr(VInside.Total) ;
sedLeave.Value := 0;
end;
end;
procedure TfrmAttendance.FormCreate(Sender: TObject) ;
begin
MuseumCount := TMuseumCount.Create;
end;
TMuseumCount does not have its own data fields or methods, so how do we use it to calculate and store the necessary values? We use the dot operator to give us access to the TCounter objects through chaining or explicit delegation. (This is familiar from the RAD objects, and we look at them later in this chapter.) We see this chaining clearly in btnEnters OnClick event handler. For example, we have the statement:
MuseumCount.VEntered.Add (sedEnter.Value) ;Let's discuss the code on the next page...

