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

Accessing an Object and its Data - Delphi OOP Part 4 / Chapter 9
Direct access properties; Processing within access methods

By Zarko Gajic, About.com

Ex 4.3 step 3 Direct access properties

In step 1 of this example the mapping methods simply provide access to the data fields (example 4.1 step 1, lines 26 or 30).

The Set procedures assign the incoming parameter to the private data field, using a single program statement.

The Get functions return the value of the underlying data field, also using a single program statement (example 4.1 step 1 lines 18 or 22). They do no extra manipulation and the access methods are there only to provide public access to the private data. Under these circumstances we can use direct mapping of properties to data fields and dispense with the access methods.

Creating properties with direct access to the underlying data gives a simpler class definition. Change the type declaration and the implementation section in ClientU.pas as follows:

unit ClientU;

interface

type
4   TClient = class (TObject)
5   private
6    FAccNo: string;
7    FCName: string;
8   public
9    constructor Create (ACName, AnAccNo: string) ;
10    destructor Destroy; override;
11    property AccNo: string read FAccNo write FAccNo;
12    property CName: string read FCName write FCName;
13 end;

14 implementation

15 { TClient }

16 { Constructor & destructor as before }

30 { No Get… or Set… methods needed }

31 end.

Instead ofreferring to access methods, the property declarations now refer directly to the underlying data field in the read and write mapping (lines 11–12). A program reference to one of these properties now results in direct access to the underlying data item. Since no access methods are needed none are declared in the type section nor are they implemented in the implementation section.

The code is significantly less, but the screen display is exactly as before.

Example 4.4 Processing within access methods

As mentioned in example 4.3 step 2, we can do additional processing within access methods. Assume that a change request comes through that client numbers are always six digits without any alphabetic characters. This means that the FAccNo data field can now be declared as an integer instead of a string (this will save storage space) and that all existing client numbers with fewer that six digits must now be prefixed with a 1 and as many zeroes as are needed to make up six digits. New client numbers will start at 200000.

Clearly we want to minimise the changes required in the program as much as possible, and the user interface at least should preferably be unaffected with changes restricted to the TClient class definition. (This is a situation where separation of concerns, as discussed in chapter 3, helps to decouple the user interface objects and the domain or application objects.)

We change the TClient class’s direct access AccNo property in example 4.3 to a mapped access and do the necessary processing within the access methods. Because we are storing the account number as an integer, the constructor converts the incoming string to an integer. For variety, we will no longer issue a message when destroying a TClient object, and so we can leave out our implementation of the destrutor and rely instead on the implicitly inherited Destroy.

unit ClientU;
interface
type
  TClient = class (TObject)
  private
   FAccNo: integer; // Now an integer
   FCName: string;
   function GetAccNo: string;
   procedure SetAccNo(const AnAccNo: string) ;
  public
   constructor Create (ACName, AnAccNo: string) ; // no destructor
   property AccNo: string read GetAccNo write SetAccNo; //method map
   property CName: string read FCName write FCName; //direct map
  end;

implementation

uses Dialogs, SysUtils; // for message & Int to Str conversions

{ TClient }
constructor TClient.Create(ACName, AnAccNo: string) ;
begin
  inherited Create; // First invoke superclass's constructor
  FAccNo := StrToInt(AnAccNo) ; // convert string to integer
  FCName := ACName;
end; // end constructor TClient.Create

function TClient.GetAccNo: string;
begin
  if FAccNo < 100000 then
    Result := IntToStr(FAccNo + 100000)
  else
    Result := IntToStr(FAccNo) ;
end;

procedure TClient.SetAccNo(const AnAccNo: string) ;
begin
  FAccNo := StrToInt(AnAccNo) ;
end;

end.
CName remains a direct mapped property (line 14) while we map AccNo through methods. AccNo is still defined as a string property to keep the interface to other units unchanged (line 13) but the underlying data field, FAccNo has become an integer (line 6). Because of this, mapping access method SetAccNo converts the incoming string to an integer (line 33).

The user interface remains unchanged, and, because of encapsulation, is unaware that the underlying data representation has changed.

Explore Delphi Programming
About.com Special Features

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

Easy ways to connect two computers for networking purposes. More >

  1. Home
  2. Computing & Technology
  3. Delphi Programming
  4. Coding Delphi Applications
  5. OOP in Delphi
  6. Free Online OOP Course
  7. Accessing an Object and its Data - Delphi OOP Part 4 / Chapter 9

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

All rights reserved.