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

Programmer Defined Classes and Objects - Delphi OOP Part 3 / Chapter 6
Using a "global" Variable; A combined User Interface / Application

By Zarko Gajic, About.com

Ex 3.1 step 1 Using a "global" Variable

... The Button btnAddItem has an OnClick event handler (lines 14, 28–31), button btnDisplay has an OnMouseDown (lines 15–16, 32–36) and an OnMouseUp event handler (lines 17–18, 37–41) and BitBtn bmbReset has an OnClick event handler (lines 13, 42–45).
unit GlobalU;

interface

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

type
7   TfrmCount = class(TForm)
8     gpbItems: TGroupBox;
9     lblTotal: TLabel;
10     bmbReset: TBitBtn;
11     btnAddItem: TButton;
12     btnDisplay: TButton;
13     procedure bmbResetClick(Sender: TObject) ;
14     procedure btnAddItemClick(Sender: TObject) ;
15     procedure btnDisplayMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer) ;
17     procedure btnDisplayMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer) ;
19   private
20     {Count: integer; // for step 2}
21   end; // end TfrmCount = class(TForm)
22 var
23   frmCount: TfrmCount;

24 implementation

25 {$R *.dfm}

26 var
27   Count: integer = 0; // for step 1; comment out declaration for step 2

28 procedure TfrmCount.btnAddItemClick(Sender: TObject) ;
29 begin
30   Inc (Count) ;
31 end;

32 procedure TfrmCount.btnDisplayMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer) ;
34 begin
351   lblTotal.Caption := IntToStr (Count) ;
36 end;

371 procedure TfrmCount.btnDisplayMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer) ;
39 begin
40   lblTotal.Caption := '';
41 end;

42 procedureTfrmCount.bmbResetClick(Sender: TObject) ;
43 begin
44   Count := 0;
45 end;

46 end.
This is a simple program that works. However it has a potential problem. Because three different procedures, the event handlers btnItemsClick, btnDisplayMouseDown and bmbResetClick all refer to the value of Count, Count must be a unit level variable (line 26–27). Giving variables unit level scope is generally not a good idea, and is usually best avoided . So in the next step we’ll make this variable part of the user interface object. Note: In Delphi a unit level variable is effectively a class variable. If several objects are created from a class with a unit level variable, the same unit level variable is available to all the objects. Each object shares the unit level variable: individual objects do not each have their own variable corresponding to the unit level variable.

Before moving on to the next step, notice that we use the expression Inc (Count) and not Count := Count + 1 in line 30. Either works, but Inc (Count) generates optimised code and so is slightly faster and is particularly useful in loops.

Ex 3.1 step 2 A combined User Interface / Application object

To do away with the unit level variable in step 1, comment out the unit level declaration (lines 26–27 above) and uncomment the form’s private data field (line 20). All references to Count in the event handlers will now refer to a private data field of the form and not to a unit level variable. Run the program and test it. To the user it works as before, but instead of the unit level variable the program now uses a private data field of the object.

This change is an improvement, but we still have a problem. We have now modified the RAD user interface class to include application data. So the user interface must know how to increment the count (line 30), access it (line 35) and reset it (line 44): the user interface must have knowledge of the details of how the application works. The principle of the separation of concerns means that a user interface should not know how the application works, but only know how to communicate with application objects in response to user input.

This change is a step in the right direction but mixing up the user interface and the application will make reuse or future change difficult. (For example, if for some unexpected reason Count in line 20 is changed to a double instead of an integer, lines 30 & 35 will both cause compilation errors.) It would be better to encapsulate application data and the operations carried out on that data separately from the user interface.

As a brief aside on programming style, we explicitly initialised the unit level variable (step 1, line 27). Delphi initialises all object data when an object is created, and so we do not need to initialise the private data field (line 20).

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. Programmer Defined Classes and Objects - Delphi OOP Part 3 / Chapter 6

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

All rights reserved.