Codequalität-Checkliste

Prüfungen für Namenskonventionen, Funktionsdesign, DRY-Prinzip und SSOT.

Diese Checkliste ergänzt die Code-Konventionen mit konkreten Prüfpunkten.

Namenskonventionen

Namespace-Pattern (MS-Stil)

[ ] Unit-Namen folgen WvdS.<Kategorie>.<Komponente>.pas
[ ] Spiegelt Microsoft .NET Struktur mit WvdS. Präfix
[ ] Beispiel: WvdS.UI.Controls.Button, WvdS.System.Logging

Klassen-Hierarchie (Borland-Stil)

[ ] Abstrakte Basis verwendet TWvdSCustom* Präfix
[ ] Öffentliche Basis verwendet TWvdSBase* Präfix
[ ] Konkrete Klassen verwenden TWvdS* Präfix
[ ] Pattern: TWvdSCustomXxx → TWvdSBaseXxx → TUserXxx

Typ-Präfixe

Kategorie Präfix Beispiel
Klassen TWvdS* TWvdSRouter, TWvdSButton
Interfaces IWvdS* IWvdSActionResult, IWvdSBindable
Exceptions EWvdS* EWvdSRoutingException
Records TWvdS* TWvdSBuildResult
Enums TWvdS* TWvdSProjectType
Callbacks TWvdS* TWvdSBuildCallback

Allgemeine Benennung

[ ] Beschreibende Namen (keine Einzelbuchstaben außer Schleifen)
[ ] Keine Abkürzungen außer bekannte (URL, HTTP, JSON)
[ ] Interfaces haben GUID für DI-Container
[ ] Private Felder: F* Präfix (FValue, FCount)
[ ] Parameter: A* Präfix (AIndex, APath)

Funktionsdesign

Größen-Richtlinien

[ ] 12-24 Zeilen ideal
[ ] Maximum 40 Zeilen (darüber aufteilen)
[ ] Maximale Verschachtelungstiefe: 3

Parameter-Richtlinien

[ ] Maximum 5-7 Parameter
[ ] Bei mehr Parametern: Record/Klasse verwenden
[ ] Optionale Parameter am Ende

Single Responsibility

[ ] Jede Funktion hat EINE Aufgabe
[ ] Funktionsname beschreibt die Aufgabe vollständig
[ ] Wenn "und" im Namen nötig → aufteilen

Verb-First Naming

[ ] Get* - Wert abrufen
[ ] Set* - Wert setzen
[ ] Calculate* - Berechnung durchführen
[ ] Process* - Verarbeitung durchführen
[ ] Validate* - Validierung durchführen
[ ] Create* - Objekt erstellen
[ ] Parse* - Eingabe parsen
[ ] Format* - Ausgabe formatieren

DRY-Prinzip

[ ] Kein duplizierter Code (mehr als 3 identische Zeilen → extrahieren)
[ ] Keine Copy-Paste-Patterns
[ ] Gemeinsame Logik in Hilfsfunktionen
[ ] Konstanten statt wiederholter Literale

Beispiel: DRY-Verletzung beheben

(* VERBOTEN - Duplizierter Code *)
procedure ProcessUserA(const AUser: TUser);
begin
  if not ValidateEmail(AUser.Email) then
    raise EValidationError.Create('Invalid email');
  if Length(AUser.Name) > 64 then
    raise EValidationError.Create('Name too long');
  (* ... weitere Verarbeitung *)
end;
 
procedure ProcessUserB(const AUser: TUser);
begin
  if not ValidateEmail(AUser.Email) then
    raise EValidationError.Create('Invalid email');
  if Length(AUser.Name) > 64 then
    raise EValidationError.Create('Name too long');
  (* ... andere Verarbeitung *)
end;
 
(* KORREKT - Gemeinsame Logik extrahiert *)
procedure ValidateUser(const AUser: TUser);
begin
  if not ValidateEmail(AUser.Email) then
    raise EValidationError.Create(rsInvalidEmail);
  if Length(AUser.Name) > MAX_NAME_LENGTH then
    raise EValidationError.Create(rsNameTooLong);
end;
 
procedure ProcessUserA(const AUser: TUser);
begin
  ValidateUser(AUser);
  (* ... weitere Verarbeitung *)
end;

SSOT-Prüfung

Single Source of Truth - Keine lokalen Kopien von Common-Code!

Common Libraries verwenden

[ ] NodeJS-APIs via ~/sources/common/web/nodejs/
    - NodeJS.FS, NodeJS.Path, NodeJS.ChildProcess
[ ] VSCode-APIs via ~/sources/common/web/vscode/
    - VSCode.Window, VSCode.Commands, VSCode.Workspace
[ ] WvdS Core via ~/sources/common/core/
    - WvdS.System.Logging, WvdS.VSCode.Security

Verboten

[ ] Keine direkten require()-Aufrufe in Extensions
[ ] Keine Duplikate von Common-Units in Extensions
[ ] Keine lokalen Wrapper-Implementierungen

Beispiel: SSOT-Verletzung

(* VERBOTEN - Lokaler require() *)
function FileExists(const APath: string): Boolean;
begin
  asm
    var fs = require('fs');  (* SSOT-Verletzung! *)
    Result = fs.existsSync(APath);
  end;
end;
 
(* KORREKT - Common Library *)
uses
  NodeJS.FS;
 
function FileExists(const APath: string): Boolean;
begin
  Result := ExistsSync(APath);  (* Aus NodeJS.FS *)
end;

Separation of Concerns

[ ] UI-Logik nur in UI-Schicht (extension_main, *Dialog)
[ ] Geschäftslogik nur in Service-Schicht (*Service)
[ ] Datenstrukturen nur in Model-Schicht (*Models)
[ ] Services rufen keine VSCode-APIs direkt auf
[ ] Models enthalten keine Logik

Schichten-Architektur

┌─────────────────────────────────────────────────┐
│  UI Layer (extension_main.pas, *Dialog.pas)    │
│  → VSCode APIs, User Interaction               │
├─────────────────────────────────────────────────┤
│  Service Layer (*Service.pas)                  │
│  → Geschäftslogik, Validierung                 │
├─────────────────────────────────────────────────┤
│  Model Layer (*Models.pas)                     │
│  → Records, Typen, Enums                       │
├─────────────────────────────────────────────────┤
│  Infrastructure (NodeJS.*, VSCode.*, WvdS.*)   │
│  → Externe APIs, Platform-Abstraktion          │
└─────────────────────────────────────────────────┘

Schnell-Checkliste zum Kopieren

Review-Checkliste (Code-Qualität):

Naming:
- [ ] Unit-Namen: WvdS.<Kategorie>.<Komponente>.pas
- [ ] Klassen: TWvdS* Präfix
- [ ] Interfaces: IWvdS* Präfix
- [ ] Beschreibende Namen (keine Abkürzungen)

Funktionen:
- [ ] 12-24 Zeilen ideal, max 40
- [ ] Max 5-7 Parameter
- [ ] Single Responsibility
- [ ] Verb-First Naming

DRY:
- [ ] Kein duplizierter Code
- [ ] Gemeinsame Logik extrahiert
- [ ] Konstanten statt Literale

SSOT:
- [ ] Common Libraries verwendet
- [ ] Keine lokalen require()-Aufrufe
- [ ] Keine Duplikate von Common-Units

SoC:
- [ ] UI nur in UI-Schicht
- [ ] Logik nur in Service-Schicht
- [ ] Services ohne direkte VSCode-Aufrufe

Siehe auch

Zuletzt geändert: den 29.01.2026 um 15:13