![]() |
|
Marco Cantù's |
Chapter 11
|
Aplikasi Delphi menggunakan unit ataupun modul program secara intensif. Sebenarnya unit merupakan dasar modularitas dalam bahasa ini sebelum adanya penggunaan class. Dalam suatu aplikasi Delphi, setiap form mempunyai unit yang bersesuaian dibelakangnya. Ketika Anda menambahkan suatu form baru ke suatu project (dengan tombol toolbar yang sesuai atau menu File > New Form), Delphi sebenarnya menambahkan suatu unit baru, yang mendefinisikan class untuk form baru tersebut.
Meskipun setiap form didefinisikan dalam suatu unit, namun tidaklah berlaku untuk kebalikannya. Unit tidaklah harus mendefinisikan form, ia dapat mendefinisikan dan menyediakan sekumpulan rutin. Dengan memilih menu File > New lalu icon Unit dalam halaman New dari Object Repository, Anda menambahkan suatu unit kosong ke project yang aktif sekarang. Unit kosong ini berisi code seperti berikut, yang membatasi bagian unit menjadi:
unit Unit1; interface implementation end.
Konsep unit sangatlah sederhana. Suatu unit mempunyai nama yang unik yang bersesuaian dengan nama file-nya, suatu bagian interface mendeklarasikan apa yang bisa dilihat oleh unit lain, dan suatu bagian implementation berisi code yang sebenarnya dan deklarasi yang tersembunyi lainnya. Akhirnya, unit dapat mempunyai bagian yang optional yaitu initialization berisi code untuk dijalankan saat program dimuat kedalam memory; dia juga dapat mempunyai bagian optional lain yaitu finalization, yang dijalankan saat program dihentikan.
Bentuk umum dari suatu unit, dengan semua kemungkinan bagian yang ada, adalah sebagai berikut:
unit unitName; interface // other units we need to refer to uses A, B, C; // exported type definition type newType = TypeDefinition; // exported constants const Zero = 0; // global variables var Total: Integer; // list of exported functions and procedures procedure MyProc; implementation uses D, E; // hidden global variable var PartialTotal: Integer; // all the exported functions must be coded procedure MyProc; begin // ... code of procedure MyProc end; initialization // optional initialization part finalization // optional clean-up code end.
Klausa uses pada bagian awal interface mengindikasikan unit lain mana yang perlu kita akses pada bagian interface dari unit. Ini termasuk unit yang mendefinisikan type data yang kita tunjuk pada definisi type data yang lain, seperti komponen yang digunakan dalam form yang kita definisikan.
Klausa uses yang kedua, berada pada bagian awal implementation, mengindikasikan unit tambahan yang perlu kita akses hanya dalam code implementation. Ketika Anda perlu untuk mereferensikan unit lain dari code routine dan method, Anda harus menambahkan beberapa elemen pada bagian klausa uses yang kedua ini, bukan pada klausa yang pertama. Semua unit yang Anda referensikan harus berada pada directory project disimpan atau directory yang termasuk dalam search path (Anda dapat mengatur search path untuk suatu project pada halaman Directories/Conditionals dari kotak dialog Project Option).
Pemrogram C++ seharusnya sadar bahwa pernyataan uses tidaklah sama dengan include directive. Efek dari pernyataan uses adalah mengimpor bagian interface yang telah di-precompile dari unit yang terdaftar. Bagian implementation suatu unit hanya diperhitungkan saat unit telah di-compile. Unit yang Anda tunjuk dapat dalam bentuk source code (PAS) atau telah ter-compile (DCU), namun proses kompilasi harus menggunakan versi Delphi yang sama.
Interface suatu unit dapat mendeklarasikan sejumlah elemen yang berbeda, termasuk procedure, function, variabel global, dan data type. Dalam aplikasi Delphi, data type cukup sering digunakan. Delphi secara otomatis meletakkan suatu data type untuk class yang baru dalam suatu unit setiap kali Anda membuat suatu form. Namun, dalam Delphi, unit tidaklah hanya diperuntukkan pendefinisian form saja. Anda dapat terus mempunyai unit tradisional, dengan function dan procedure, dan Anda juga dapat mempunyai unit dengan class yang tidak menunjuk ke form atau elemen visual lainnya.
Any declarations in the interface portion of a unit are accessible from any part of the program that includes the unit in its uses clause. Variables of form classes are declared in the same way, so that you can refer to a form (and its public fields, methods, properties, and components) from the code of any other form. Of course, it’s poor programming practice to declare everything as global. Besides the obvious memory consumption problems, using global variables makes a program less easy to maintain and update. In short, you should use the smallest possible number of global variables.
The uses statement is the standard technique to access the scope of another unit. At that point you can access the definitions of the unit. But it might happen that two units you refer to declare the same identifier; that is, you might have two classes or two routines with the same name.
In this case you can simply use the unit name to prefix the name of the type or routine defined in the unit. For example, you can refer to the ComputeTotal procedure defined in the given Totals unit as Totals.ComputeTotal. This should not be required very often, as you are strongly advised against using the same name for two different things in a program.
However, if you look into the VCL library and the Windows files, you’ll find that some Delphi functions have the same name as (but generally different parameters than) some Windows API functions available in Delphi itself. An example is the simple Beep procedure.
If you create a new Delphi program, add a button, and write the following code:
procedure TForm1.Button1Click(Sender: TObject); begin Beep; end;
then as soon as you press the button you’ll hear a short sound. Now, move to the uses statement of the unit and change the code from this:
uses Windows, Messages, SysUtils, Classes, ...
to this very similar version (simply moving the SysUtils unit before the Windows unit):
uses SysUtils, Windows, Messages, Classes, ...
If you now try to recompile this code, you’ll get a compiler error: "Not enough actual parameters." The problem is that the Windows unit defines another Beep function with two parameters. Stated more generally, what happens in the definitions of the first units you include in the uses statement might be hidden by corresponding definitions of later units. The safe solution is actually quite simple:
procedure TForm1.Button1Click(Sender: TObject); begin SysUtils.Beep; end;
This code will compile regardless of the order of the units in the uses statements. There are few other name clashes in Delphi, simply because Delphi code is generally hosted by methods of classes. Having two methods with the same name in two different classes doesn’t create any problem. The problems arise only with global routines.
A Delphi application consists of two kinds of source code files: one or more units and one program file. The units can be considered secondary files, which are referred to by the main part of the application, the program. In theory, this is true. In practice, the program file is usually an automatically generated file with a limited role. It simply needs to start up the program, running the main form. The code of the program file, or Delphi project file (DPR), can be edited either manually or by using the Project Manager and some of the Project Options related to the application object and the forms.
The structure of the program file is usually much simpler than the structure of the units. Here is the source code of a sample program file:
program Project1; uses Forms, Unit1 in ‘Unit1.PAS’ {Form1DateForm}; begin Application.Initialize; Application.CreateForm (TForm1, Form1); Application.Run; end.
As you can see, there is simply a uses section and the main code of the application, enclosed by the begin and end keywords. The program’s uses statement is particularly important, because it is used to manage the compilation and linking of the application.
At least for the moment, this chapter on the structure of a Pascal application written in Delphi or with one of the latest versions of Turbo Pascal, is the last of the book. Feel free to email me your comment and requests.
If after this introduction on the Pascal language you want to delve into the object-oriented elements of Object Pascal in Delphi, you can refer to my published book Mastering Delphi 5 (Sybex, 1999). For more information on this and more advanced books of mine (and of other authors as well) you can refer to my web site, www.marcocantu.com. The same site hosts updated versions of this book, and its examples.
© Copyright Marco Cantù, Wintech Italia Srl 1995-2000
© Copyright of the Indonesian Translation by Hianoto Santoso, 2002