Some thoughts about development habits feel like they are stuck in your throat and you won’t be able to spit them out. Looking at the motivation for posting, of course I don't rule out the possibility of cheating to gain participation points, but on the other hand, I also hope to provide some suggestions or reference to fellow practitioners (Nian Xing) (I hope I don't mislead others). At the same time, I also hope that you can express your opinions on these bad habits of mine and provide criticism and corrections. Thanks.
one. Create project directory
First of all, the first step is, of course, to create a separate directory for the new project (don’t laugh). The directory name must have the same name as the project name, or another name may be used, as long as it is clear and concise. Then, create each of the following directories within this directory:
<Doc>: used to store development documents related to the project (requirements description, outline design, detailed design, etc.);
<Source>: used to store ".DPR", ".Pas", ".Dfm" and other files in the Delphi source program;
<Dcu>: ".Dcu" files are stored in this directory. The purpose of storing ".Pas" and ".Dcu" files separately is to make the contents of the Source directory clearer;
<Bin>: Stores the output files of the project, such as ".Exe", ".Dll" or ".Ocx", etc.;
<Log>: used to store log files; usually I will put a "<Project Name>Programmer Log.Txt" file in this directory.
<Images>: Of course, it is the directory where images used in the project are stored. Under normal circumstances, this directory is indispensable. If other resources are also used, then create their own directories as well, such as Wav, Avi, etc.
two. Set project options
Create a new project in Delphi, save this project to the Source directory, and at the same time:
a. Choose an icon that is eye-catching and somewhat related to the project as the icon for this project. Of course, this icon may only be used temporarily, but it must be better than the ugly one that Delphi defaults to. Otherwise, how can you be worthy of yourself?
b. Set the Output Directory in the Project Options -> Directories/Conditionals page to the Bin directory;
c. Set the Unit output Directory to the Dcu directory.
three. Add constant unit
Add a new Unit and save it as "unt<project name> Consts.Pas" to save the constants used in the project.
Four. About Form and Unit
Name the Form according to the Hungarian naming convention. A form used to log in can be named 'FrmLogin', and its unit name can be 'untLogin'. In general, the names of two corresponding Forms and Units should be consistent except for the abbreviation of 'Frm' or 'unt'.
Add a comment for this unit at the head of the Unit. The format of the comment can refer to the Delphi source code, but it should at least include the following items: function description; author; copyright; creation time; last modification time; modification history, etc.
Set the Caption of the newly created Form to the name of the Form class instead of using Delphi's default one. For example, after renaming Form1 to FrmLogin, we obtain the new form class TFrmLogin, and Delphi automatically updates the Caption of the form to 'FrmLogin'. In my opinion, the Caption should be 'TFrmLogin', because we are designing a form class TFrmLogin, rather than just operating on FrmLogin.
For a form class with clear functions like TFrmLogin, many people have the habit of setting its Caption to a name such as "Operator Login" during the design stage. My habit is that constants like "operator login" are usually stored in unt<project name>Consts.Pas and defined with ResourceString or Const. As for the naming of the form's Caption, it should be a run-time task. Therefore, I often operate Caption only when the TForm.OnCreate event is triggered, such as:
procedure TFrmLogin.FormCreate(Sender: TObject);
begin
Caption := csLoginTitle;
....
end;
five. About the use of Format function
There are three data: iYear, iMonth, and iDay. To display information such as "Birthday: 1976/3/18", what do you usually do? Use s := 'Birthday:'+IntToStr(iYear)+'.'+IntToStr(iMonth)+'.'+IntToStr(iDay);? This is really tiring. My habit is to add a constant csBirthDayFormat = 'Birthday: %d/%d/%d' in unt<project name>Consts.Pas to save the display format, and then use s := Format(csBirthDayFormat, [iYear, iMonth , iDay]); Such statements complete the assembly of data. The advantage of doing this is obvious, that is, you only need to maintain the display format of the data in one place.
The Format function is powerful and I highly recommend it. What about you?
six. About the storage of registry or Ini files
Originally, I usually used TRegistry to access the registry, and TIniFile to access Ini files. The usage of these two classes is different, so it is almost impossible to use the same code to access both the registry and the Ini file. What a headache!
Finally I found a savior! It is the TRegistryIniFile class. Looking at the Registry unit, we find that TRegistryIniFile inherits from TCusomIniFile. TIniFile also inherits from TCusomIniFile. Therefore, using the abstract class TCusomIniFile to achieve access to the registry or Ini file is to kill two birds with one stone. for example:
var
csmIniFile:TCusomIniFile;
begin
if blUseIniFile then//If using Ini file
csmIniFile:= TIniFile.Create(csRootKey)
else
csmIniFile:= TRegistryIniFile.Create(csRootKey);
//Then you can use csmIniFile to access the Ini file.
//Or access the registry in a similar way to accessing the Ini file.
seven. About TStream streams and TFileStream, TMemoryStream, etc.
Both TFileStream and TMemoryStream inherit from the abstract class TStream, which means that we can use a set of codes to complete access operations to files and memory. Therefore, when defining some interfaces, I tend to define the types of parameters as abstract classes rather than concrete classes. For example, a function to complete the saving function is defined as
function Save(AStream: TStream): Boolean;
than defined as
function Save(AStream: TFileStream): Boolean;
Be much more flexible.
The former definition is forward-looking because it can be applied to new types of flows that may appear in the future. The latter definition only applies to streams such as TFileStream (including subclasses of TFileStream, of course), which is much more rigid.
My habit: If there is an abstract class, try to define the parameters as the type of the abstract class. After all, we cannot foresee the future.
eight. Use TAction more
Delphi 4 and later introduced the concept of Action, and added the TActionList component to the Standard component bar. The advantage of using Action is that the worries of control state synchronization are gone!
More articles
Musicwind®@HangZhou.Zj.China