Delphi Clean Code

SkillDev tools

Pragmatic clean code standards for Delphi — concise, direct, no over-engineering

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Delphi Clean Code skill

What this skill tells your AI

The instructions your AI receives, as published by delphicleancode/delphi-spec-kit in .claude/skills/clean-code/SKILL.md and read by ahel’s review.

CRITICAL SKILL — Be concise, direct and solution-focused.

Fundamental Principles

PrincipleRule
SRPA function/class does ONE thing
DRYDon't repeat code — extract and reuse
KISSSimplest solution that works
YAGNIDon't build what wasn't asked for
Boy ScoutLeave the code better than you found it

Naming Rules (Pascal Guide)

ElementConvention
VariablesReveal intent: LCustomerCount not N
MethodsVerb + noun: GetCustomerById not Customer
BooleansQuestion form: IsActive, HasPermission, CanEdit
ConstantsSCREAMING_SNAKE: MAX_RETRY_COUNT
FieldsPrefix F: FCustomerName
ParametersPrefix A: ACustomerName
Var. locationsPrefix L: LCustomer

Rule: If you need a comment to explain a name, rename it.

Method Rules

RuleDescription
ShortMaximum 20 lines, ideal 5-10
One ThingDo one thing and do it well
One LevelOne level of abstraction per method
Few ArgsMaximum 3 arguments, prefer 0-2
No Side EffectsDon't mute inputs unexpectedly

Code Structure

StandardApplication
Guard ClausesEarly returns for edge cases
Flat > NestedAvoid deep nesting (max 2 levels)
CompositionSmall compound methods
ColocationRelated code together

Guard Clauses in Delphi

//❌ BAD — excessive nesting
procedure ProcessOrder(AOrder: TOrder);
begin
  if Assigned(AOrder) then
  begin
    if AOrder.Items.Count > 0 then
    begin
      if AOrder.IsValid then
      begin
        //real logic here
      end;
    end;
  end;
end;

//✅ BOM — guard clauses
procedure ProcessOrder(AOrder: TOrder);
begin
  if not Assigned(AOrder) then
    raise EArgumentNilException.Create('AOrder cannot be nil');
  if AOrder.Items.Count = 0 then
    raise EBusinessRuleException.Create('Order must have items');
  if not AOrder.IsValid then
    raise EValidationException.Create('Order validation failed');

  //real logic here — no nesting
end;

Anti-Patterns (DO NOT DO)

❌ Pattern✅ Fix
Comment each lineDelete obvious comments
Method > 20 linesShare by responsibility
Magic numbersNamed constants
with statementExplicit local variables
Global variablesConstructor injection
Generic CatchSpecific exceptions
Logic in OnClickDelegate to Service
God class / God unityOne class = one responsibility
Ignore Freetry/finally always

Memory Management

//✅ Temporary objects — always try/finally
LList := TStringList.Create;
try
  LList.Add('item');
  //use LList
finally
  LList.Free;
end;

//✅ Interfaces — reference counting automático
var LService: IMyService;
LService := TMyService.Create; //automatically released

//✅ Owner pattern for visual components
LButton := TButton.Create(Self); //Self frees automatically

AI Code Style

SituationAction
User requests featureWrite directly
User reports bugCorrect, don't explain
Requirement unclearAsk, don't assume

🔴 Before Editing (THINK FIRST!)

QuestionWhy
Which units use this?They can break
What does this unit matter?Interfaces can change
What tests cover this?Tests may fail
Is it a shared component?Multiple points affected

🔴 Rule: Edit the file + all dependents in the SAME task.

🔴 Self-Check (MANDATORY)

CheckPergunta
Goal achieved?Did I do exactly what was asked?
Edited files?Have I modified everything necessary?
Does the code work?Have I tested/verified?
No errors?Compiles without warnings?
Nothing forgotten?Edge cases treated?
Memory safe?Objects released correctly?

🔴 Rule: If ANY check fails, correct it before finishing.

Signals

GitHub stars
50
Forks
14
Last commit
Mar 2026
Advanced
Catalog kind
skill
Gateway key
delphi-clean-code
Source
github.com/delphicleancode/delphi-spec-kit