Dear All,
I'm not quite sure whether to consider this a recommendation, reminder, or just an annoyance when I observe much of the code I find for Delphi. Obviously, Delphi has been made so you can build powerful apps in an easy pascal language. However, all Delphi users must keep in mind the overall purpose of Object Oriented Pascal.
By default, you create a new application, and maybe 80% of the time you would immediately start dropping components onto the main form. You would be surprised how many people don't understand how the form is really created behind the scenes. Now I'm sure we all know what objects are, of course. A form is an object. You declare it at the top, and implement it (if any) at the bottom. This applies literally for ALL components out there.
Now for making very simple applications and small examples, no biggie to throw a few controls on a form and work directly with those controls from wherever, even other units. I, however, absolutely hate storing variables basically wherever, whether in the form's private, public, or even outside the form component. 98% of the time, I create an object for every conceivable set of similar information before I ever drop any components onto a form, and I do so in a unit of its own.
For those who are going 'huh?'... take this example of storing DB connection info:
Now how would I go about this? Simple..
This way, everything which is related to each other is contained within its own object.
Now there are many other things you can do with this, like with this example, I could put a TADOConnection directly in this object, auto create/destroy it in the object's constructor/destructor methods, and direct the properties to automatically create the connection string upon connecting. This involves a lot more hands-on work, which I've already done (however very specific to my own needs so I'm not very willing to post everything I have).
To make a long story short, however, the point of using objects is to capture all commonly working code into one single place. This keeps you organized, flexible, and it's reusable. Of course my example above I made the object in the same unit, which it's recommended to put them in their own units.
Generally, almost all of delphi is already object oriented pascal, and it breaks my heart to see people not using its capabilities as they should. Most of you **should** know what I'm talking about, but this reminder goes out for those who don't seem to get it.
I'm not quite sure whether to consider this a recommendation, reminder, or just an annoyance when I observe much of the code I find for Delphi. Obviously, Delphi has been made so you can build powerful apps in an easy pascal language. However, all Delphi users must keep in mind the overall purpose of Object Oriented Pascal.
By default, you create a new application, and maybe 80% of the time you would immediately start dropping components onto the main form. You would be surprised how many people don't understand how the form is really created behind the scenes. Now I'm sure we all know what objects are, of course. A form is an object. You declare it at the top, and implement it (if any) at the bottom. This applies literally for ALL components out there.
Now for making very simple applications and small examples, no biggie to throw a few controls on a form and work directly with those controls from wherever, even other units. I, however, absolutely hate storing variables basically wherever, whether in the form's private, public, or even outside the form component. 98% of the time, I create an object for every conceivable set of similar information before I ever drop any components onto a form, and I do so in a unit of its own.
For those who are going 'huh?'... take this example of storing DB connection info:
Code:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, ADODB;
type
TForm1 = class(TForm)
ADOConnection1: TADOConnection;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
ServerName: String;
DatabaseName: String;
LoginName: String;
Password: String;
Provider: String;
Persist: Boolean;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
ServerName:= 'MyServerName\Instance';
DatabaseName:= 'MyDatabaseName';
LoginName:= 'sa';
Password:= 'yourpasswordhere';
Provider:= 'SQLOLEDB.1';
Persist:= False;
ADOConnection1.ConnectionString:=
'Provider=' + Provider +
';Password=' + Password +
';Persist Security Info=';
if Persist then
ADOConnection1.ConnectionString:= ADOConnection1.ConnectionString + 'True'
else
ADOConnection1.ConnectionString:= ADOConnection1.ConnectionString + 'False';
ADOConnection1.ConnectionString:= ADOConnection1.ConnectionString +
';User ID=' + LoginName +
';Initial Catalog=' + DatabaseName +
';Data Source=' + ServerName;
end;
end.
Now how would I go about this? Simple..
Code:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, ADODB;
type
TDBProvider = (dpSQLOLEDB, dpSQLNCLI);
TDBConnection = class(TObject)
private
fServer: String;
fDatabase: String;
fLogin: String;
fPassword: String;
fProvider: TDBProvider;
fPersist: Boolean;
function GetConnectionString: String;
public
constructor Create; override;
constructor Create(Server: String; Database: String; Login: String;
Password: String; Provider: TDBProvider; Persist: Boolean); override;
property Server: String read fServer write fServer;
property Database: String read fDatabase write fDatabase;
property Login: String read fLogin write fLogin;
property Password: String read fPassword write fPassword;
property Provider: TDBProvider read fProvider write fProvider;
property Persist: Boolean read fPersist write fPersist;
property ConnectionString: String read GetConnectionString;
end;
TForm1 = class(TForm)
ADOConnection1: TADOConnection;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
Connection: TDBConnection;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
Connection.Server:= 'MyServerName\Instance';
Connection.Database:= 'MyDatabaseName';
Connection.Login:= 'sa';
Connection.Password:= 'yourpasswordhere';
Connection.Provider:= dpSQLOLEDB;
Connection.Persist:= False;
ADOConnection1.ConnectionString:= Connection.ConnectionString;
end;
function TDBConnection.GetConnectionString: String;
var
Pers, Prov: String;
begin
//I would normally do more error checking here
if Self.fPersist then
Pers:= 'True'
else
Pers:= 'False';
case Self.fProvider of
dpSQLOLEDB: Prov:= 'SQLOLEDB.1';
dpSQLNCLI: Prov:= 'SQLNCLI';
end;
Result:=
'Provider=' + Prov +
';Password=' + Password +
';Persist Security Info=' + Pers +
';User ID=' + LoginName +
';Initial Catalog=' + DatabaseName +
';Data Source=' + ServerName;
end;
constructor TDBConnection.Create;
begin
//Default values
Self.fServer:= '(local)';
Self.fDatabase:= 'master';
Self.fLogin:= 'sa';
Self.fPassword:= '';
Self.fProvider:= dpSQLOLEDB;
Self.fPersist:= False;
end;
constructor TDBConnection.Create(Server: String; Database: String; Login: String;
Password: String; Provider: TDBProvider; Persist: Boolean);
begin
Self.fServer:= Server;
Self.fDatabase:= Database;
Self.fLogin:= Login;
Self.fPassword:= Password;
Self.fProvider:= Provider;
Self.fPersist:= Persist;
end;
end.
This way, everything which is related to each other is contained within its own object.
Now there are many other things you can do with this, like with this example, I could put a TADOConnection directly in this object, auto create/destroy it in the object's constructor/destructor methods, and direct the properties to automatically create the connection string upon connecting. This involves a lot more hands-on work, which I've already done (however very specific to my own needs so I'm not very willing to post everything I have).
To make a long story short, however, the point of using objects is to capture all commonly working code into one single place. This keeps you organized, flexible, and it's reusable. Of course my example above I made the object in the same unit, which it's recommended to put them in their own units.
Generally, almost all of delphi is already object oriented pascal, and it breaks my heart to see people not using its capabilities as they should. Most of you **should** know what I'm talking about, but this reminder goes out for those who don't seem to get it.