1. Home
  2. Computing & Technology
  3. Delphi Programming

Indirection - Delphi OOP Part 8 - Chapter 18

By , About.com Guide

Example 8.5 RAD Delegation

Our aim in this example is to provide encapsulation for objects on a user interface.

We will create and initialise the private objects ourselves at run-time and will expose whatever operations are needed by creating appropriate access methods or properties to delegate the operations to the private constituent objects.

Ex 8.5 step 1 Creating the delegation

We’ll apply this principle to the previous example. In the user interface class TfrmBulkMags we make edtPriceKg private so that it cannot be accessed from outside this unit. Now we provide a public read-only PriceKg property to access its Text property. (We could also use a public GetPriceKg access method.) Because we want edtPriceKg to be private, we are bypassing the RAD feature and so we must now create and initialise edtPriceKg at run time.
unit RADdelegationU;

// Replacing RAD implicit
// delegation by explicit delegation


interface

uses
   Windows, Messages, SysUtils, Variants, Classes,
   Graphics, Controls, Forms, Dialogs, StdCtrls;

type
   TfrmBulkMags = class(TForm)
     gpbPriceKg: TGroupBox;
     procedure FormCreate(Sender: TObject) ;
   private
     edtPriceKg: TEdit;
     function GetPriceKg: double;
   public
     property PriceKg: double read GetPriceKg;
   end;

var
   frmBulkMags: TfrmBulkMags;

implementation

{$R *.dfm}

procedure TfrmBulkMags.FormCreate(Sender: TObject) ;
begin
   edtPriceKg := TEdit.Create(self) ;
   with edtPriceKg do
   begin
     Parent := gpbPriceKg;
     Left := 24;
     Top := 24;
     Width := 121;
     Height := 21;
     Text := '11.99';
   end;
end;

function TfrmBulkMags.GetPriceKg: double;
begin
   // delegate retrieval
   Result := StrToFloat (edtPriceKg.Text) ;
end;

end.
Any class outside this unit can now access the value of edtPriceKg’s Text property only through the PriceKg property, and cannot access any of edtPriceKg’s other properties. This provides the typical advantages of encapsulation. If the representation of the price needs to change, possibly from a TEdit to a TLabel, we change the component and the GetPriceKg mapping method to read the TLabel instead of the TEdit.

This change is restricted to this class and client objects remain unaware of the change since they continue to use the PriceKg property. The representation of PriceKg on the user interface is no longer of concern to the client objects, which are now concerned simply with the ‘GetPriceKg’ concept and not with its implementation details.

Ex 8.5 step 2 Using the delegation

To use the access method provided on frmBulkMags, btnCalculate’s OnClick event handler changes as follows from the version in example 8.4. This program simply uses the frmBulkMags.PriceKg property and is unaware of and unconcerned about how TfrmBulkMags implements it.
procedure TfrmCashRegister.btnCalculateClick(Sender: TObject) ;
var
   NoOfKgs, TotalPrice: double;
begin
   // frmBulkMags encapsulation maintained through the Text property
   NoOfKgs := StrToFloat (edtWeightKg.Text) ;
   TotalPrice := frmBulkMags.PriceKg * NoOfKgs;
   lblTotalPrice.Caption := FloatToStrF(TotalPrice,ffCurrency,10,2) ;
   bmbReset.SetFocus;
end;
To summarise, client classes have no access to any of the composed object’s constituents except to what is exposed by the composed object through public visibility (eg public properties or access methods). So in example 8.5 no objects outside unit BulkMagsU can set, for example, the Top or Width properties of the TEdit object. In example 8.4, where the TEdit object is declared with published visibility, any outside object can change any of its properties.

RAD gives all the constituent objects on the user interface published access so that they can appear in and be manipulated through the Object Inspector and so that they can appear on the Form. RAD also declares a variable in the same unit as the class definition. In these respects, we don’t copy the RAD code for our classes. Instead we use (implicit) delegation: we make our constituent objects private (or protected) and provide access methods or properties only for those aspects that we want to make available to client objects. When dealing with RAD objects, this approach is useful, particularly where only a few RAD objects are concerned. But in larger programs it becomes cumbersome. Fortunately it is not the only way to counteract the problems associated with the chaining inherent in RAD generated code. As an alternative approach, in chapter 10 we’ll adopt the ‘intermediate object’ strategy of example 8.3 to develop the Facade pattern.

Explore Delphi Programming
About.com Special Features

Holiday Central

What to eat, where to go, fun things to do and how to save money on the perfect gifts. More >

Family Tech Center

Stay connected and entertained with reviews on tips on the latest HDTVs, cellphones and more. More >

  1. Home
  2. Computing & Technology
  3. Delphi Programming
  4. Coding Delphi Applications
  5. OOP in Delphi
  6. Free Online OOP Course
  7. Indirection - Delphi OOP Part 8 - Chapter 18

©2009 About.com, a part of The New York Times Company.

All rights reserved.