Servizi informatici per le aziende

Convenzioni per lo sviluppo (parte I)

Nomenclatura:

Layout del codice:

Nomenclatura

Utilizzo di GExperts per scrivere i commenti

La funzionalità macro di GExperts in Delphi permette di velocizzare la scrittura dei commenti al codice tramite delle comode combinazioni di tasti. Lo strumento si occuperà infatti di inserire tutta la struttura del commento, comprensiva della data, dell'autore e dei nomi dei parametri; lasciando allo sviluppatore solo il compito di riempire le descrizioni specifiche per ogni funzione.

Sarà sufficente importare lo script:

     CodeToDocTemplate.xml

dal menù GEXperts » Configuration… » Editor Experts » Expand Macro Template » Configure » Import… di Delphi e personalizzare il template con il proprio nome e le proprie preferenze.

Il template è conforme al formato richiesto da DelphiCodeToDoc e si utilizza posizionando il cursore sopra la linea da commentare ed utilizzando i tasti di scelta rapida, personalizzabili se occorre, Shift+Alt+1 per le classi, Shift+Alt+2 per funzioni o procedure, Shift+Alt+3 per le units e Shift+Alt+4 per le variabili.

Definizione delle funzioni e delle procedure

I nomi delle funzioni vengono preceduti dal prefisso fn mentre le procedure dal prefisso proc, seguita dal nome vero e proprio che deve cominciare con una lettera maiuscola.

Es.

function fnCreaTabelle: Boolean;
procedure TFrm_Calendario.procFillMese;

Ogni funzione o procedura deve essere opportunamente commentata ed identificata. La struttura di tale commento è la seguente:

  1. Una riga di asterischi preceduta da una parentesi graffa aperta.
  2. Una riga che indica lo stato di stesura del codice, ovvero se la funzione è definitiva, non definitiva, per debug.
  3. Il nome della procedura o funzione.
  4. La funzionalità.
  5. I parametri.
  6. I valori di ritorno per le funzioni.
  7. La data di creazione e l'autore.
  8. Eventuali note sulle variazioni compiute.
  9. Una riga di asterischi seguita da una parentesi graffa chiusa.
  10. Dichiarazione della funzione.

Es.

{*****************************************************************************
* Stato : definitiva
* Nome : fnCreaTabelle
* Funzionalità : Creazione delle tabelle usate dall'applicazione.
* Viene chiamata quando faccio partire l'applicazione
* con l'opzione a riga di comando /c
* Parametri : Nessuno
* Valori di ritorno : Ritorna TRUE se la creazione è andata a buon fine
* Data di creazione : 20/4/2000 - Alberto Zen
* Variazioni : 21/4/2000 - Alberto Zen - Aggiunto un nuovo campo alla
* tabella manutenzioni.db
*****************************************************************************}

function fnCreaTabelle: Boolean;

Scrittura delle costanti

Le costanti vanno indicate tutte con lettere maiuscole. Per quanto riguarda la loro denominazione, si rimanda al programmatore l'uso di un nome adeguato.

Es.

const
PI = 3.14159;
ANSWER = 342;
PRODUCTNAME = 'Delphi';

Nomi dei moduli

Le form debbono essere nominate aggiungendo al nome il prefisso Frm_, i report con il prefisso Rep_.

La form principale di ogni programma, ossia la form che viene visualizzata all'apertura del programma stesso, deve sempre essere nominata come Frm_Main.

Es.

Frm_Calendario: TFrm_Calendario;
Rep_Bolla: TRep_Bolla;

Layout del codice

Nidificazioni

Le nidificazioni devono avere la seguente struttura:

  • Struttura if…then: Lo statement posto dopo il then va collocato nella riga successiva spostato a destra di una tabulazione.

Es.

if (idOperatore = -1) then
Application.Terminate

Se gli statement da eseguire dopo il then sono più di uno la sintassi è la seguente:

Es.

if (sDBPath = '') then
begin
Frm_DBPath := TFrm_DBPath.Create(self);
Frm_DBPath.ShowModal;
sDBPath := Frm_DBPath.txtPath.Text;
Ini.WriteString('Generale', 'Percorso', sDBPath);
Frm_DBPath.Free;
end;

  • Struttura with…do, while…do, for…to, repeat…until: Lo statement posto dopo va collocato nella riga successiva spostato a destra di una tabulazione.

Es.

while (not EOF) do
begin
Nodo := twTreeView.Items.AddChild(Root, FieldByName('sDescrizione').AsString);
Nodo.ImageIndex := 1;
Nodo.SelectedIndex := 1;
Nodo.Data := Pointer(FieldByName('iID').AsInteger);
twTreeView.Items.AddChild(Nodo, 'dummy');
Next;
end;

  • Struttura case…of: Gli statement successivi vanno collocati nella riga successiva spostato a destra di una tabulazione.

Es.

case Node.Level of
1: AllowExpansion := FillPratica(Node, Integer(Node.Data), bFillTree);
2: AddPraticaList(Integer(Node.Data));
end;

Nel caso di nidificazioni successive il layout è il seguente:

Es.

case Node.Level of
1: AllowExpansion := FillPratica(Node, Integer(Node.Data), bFillTree);
2: AddPraticaList(Integer(Node.Data));
3:
begin
case Node.ImageIndex of
6: AllowExpansion := FillFattureIn(Node, Integer(Node.Data), bFillTree);
5: AllowExpansion := FillBuoniOrdine(Node, Integer(Node.Data), bFillTree);
3: AllowExpansion := FillPreventivi(Node, Integer(Node.Data), bFillTree);
end; //case
end;
end; //case

Il blocco va concluso con un commento relativo allo statement che lo apre se siamo in presenza di blocchi nidificati.

Es.

with QClienti do
begin
Active := TRUE;
while (not EOF) do
begin
Nodo := twTreeView.Items.AddChild(Root, FieldByName('sDescrizione').AsString);
Nodo.ImageIndex := 1;
Nodo.SelectedIndex := 1;
Nodo.Data := Pointer(FieldByName('iID').AsInteger);
TreeView.Items.AddChild(Nodo, 'dummy');
Next;
end; //while
Active := FALSE;
end; //with

Spaziature

Tra gli operandi e gli operatori è necessario inserire uno spazio anche se non richiesto necessariamente dalla sintassi del linguaggio.

Es.

DBPathFrm:=TDBPathFrm.Create(self);

Diventa:

Es.

DBPathFrm := TDBPathFrm.Create(self);

Ciò al fine di garantire una più immediata interpretazione del codice.

Allineamenti

Gli allineamenti del codice vengono utilizzati per creare raggruppamenti grafici per identificare raggruppamenti logici di operazioni, come, ad esempio, l'assegnazione di un insieme di proprietà di un oggetto. In tal modo è possibile identificare a colpo d'occhio le assegnazioni ai vari oggetti.

Es.

procedure TMainFrm.ToolbarButton976Click(Sender: TObject);
begin
// Creo un nuovo preventivo
with DM.TPreventivi do
begin
Append;
// Aggiungo data e operatore
FieldByName('Data').AsDateTime := Now();
FieldByName('idOperatore').AsInteger := idOperatore;
FieldByName('Accettato').AsBoolean := FALSE;
FieldByName('Inviato').AsBoolean := FALSE;
FieldByName('Convalidato').AsBoolean := FALSE;
FieldByName('bAnnullato').AsBoolean := FALSE;
FieldByName('bUsoInterno').AsBoolean := FALSE;
FieldByName('iAzienda').AsInteger := iAzienda;
Post;
PreventivoFrm := TPreventivoFrm.Create(Self);
PreventivoFrm.TPreventivi.Filter := 'iID=' + DM.TPreventivi.FieldByName('iID').AsString;
PreventivoFrm.TPreventivi.Filtered := TRUE;
PreventivoFrm.sRuolo := sRuolo;
PreventivoFrm.iDOperatore := iDOperatore;
if (sRuolo <> 'Amministratore') then
PreventivoFrm.DBCheckBox3.Enabled := FALSE;
end; //with
end;