acbr-components
Architectural, dependency injection and UI patterns for the ACBr Project (Commercial Automation Brazil) ecosystem in Delphi.
Refactoring techniques for Object Pascal focused on improving readability, removing code smells, and preserving behavior through practices like Extract Method, Guard Clauses, and polymorphism.
$ npx -y skills add delphicleancode/delphi-spec-kit --skill refactoring --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/refactoringContext preview
The summary Claude sees to decide when to auto-load this skill.
Refactoring techniques for Object Pascal focused on improving readability, removing code smells, and preserving behavior through practices like Extract Method, Guard Clauses, and polymorphism.
name: "Delphi Code Refactoring" description: "Refactoring techniques for Object Pascal focused on improving readability, removing code smells, and preserving behavior through practices like Extract Method, Guard Clauses, and polymorphism."
Use this skill when the user requests refactoring, code review or removal of code smells in Object Pascal. Refactoring **never changes observable behavior** — it only improves the internal structure of the code.
> "Refactoring is the art of changing the structure of code without changing its behavior." > Always write (or check for) tests **before** refactoring.
---
**Detect:** Method with more than 20 lines or that needs comments to explain blocks.
**Before:**
procedure TInvoiceService.GenerateInvoice(AOrder: TOrder);
var
LTax, LSubtotal, LTotal: Currency;
LItem: TOrderItem;
LLines: TStringList;
begin
//Calculate subtotal
LSubtotal := 0;
for LItem in AOrder.Items do
LSubtotal += LItem.UnitPrice * LItem.Quantity;
//Calculates tax
if AOrder.IsExempt then LTax := 0
else LTax := LSubtotal * 0.12;
LTotal := LSubtotal + LTax;
//Generates report lines
LLines := TStringList.Create;
try
LLines.Add('NOTA FISCAL');
LLines.Add(Format('Cliente: %s', [AOrder.Customer.Name]));
for LItem in AOrder.Items do
LLines.Add(Format(' %s x%d = R$%.2f',
[LItem.Product.Name, LItem.Quantity, LItem.UnitPrice * LItem.Quantity]));
LLines.Add(Format('Total: R$%.2f', [LTotal]));
LLines.SaveToFile(AOrder.InvoicePath);
finally
LLines.Free;
end;
end;**After:**
procedure TInvoiceService.GenerateInvoice(AOrder: TOrder);
var
LSubtotal, LTax: Currency;
begin
LSubtotal := CalculateSubtotal(AOrder);
LTax := CalculateTax(AOrder, LSubtotal);
SaveInvoiceFile(AOrder, LSubtotal + LTax);
end;
function TInvoiceService.CalculateSubtotal(AOrder: TOrder): Currency;
var LItem: TOrderItem;
begin
Result := 0;
for LItem in AOrder.Items do
Result := Result + (LItem.UnitPrice * LItem.Quantity);
end;
function TInvoiceService.CalculateTax(AOrder: TOrder; ASubtotal: Currency): Currency;
const
STANDARD_TAX_RATE = 0.12;
begin
if AOrder.IsExempt then Result := 0
else Result := ASubtotal * STANDARD_TAX_RATE;
end;
procedure TInvoiceService.SaveInvoiceFile(AOrder: TOrder; ATotal: Currency);
var
LLines: TStringList;
LItem: TOrderItem;
begin
LLines := TStringList.Create;
try
LLines.Add('NOTA FISCAL');
LLines.Add(Format('Cliente: %s', [AOrder.Customer.Name]));
for LItem in AOrder.Items do
LLines.Add(Format(' %s x%d = R$%.2f',
[LItem.Product.Name, LItem.Quantity, LItem.UnitPrice * LItem.Quantity]));
LLines.Add(Format('Total: R$%.2f', [ATotal]));
LLines.SaveToFile(AOrder.InvoicePath);
finally
LLines.Free;
end;
end;---
**Detect:** Class with fields of different nature, methods without cohesion.
**Before:**
TEmployee = class private //Personal data FName: string; FBirthDate: TDate; FCpf: string; //Salary data FBaseSalary: Currency; FBonusPercentage: Double; FDepartmentId: Integer; //HR Data FHiredDate: TDate; FVacationDaysLeft: Integer; FPerformanceScore: Integer; public function CalculateGrossSalary: Currency; function CalculateNetSalary: Currency; function CalculateVacationPay: Currency; function GetNextVacationDate: TDate; function GetYearsOfService: Integer; function IsEligibleForBonus: Boolean; end;
**After:**
//Value Object — immutable
TEmployeePersonalData = record
Name: string;
BirthDate: TDate;
Cpf: string;
end;
//Cohesive class: salary responsibility
TEmployeeSalary = class
private
FBaseSalary: Currency;
FBonusPercentage: Double;
public
constructor Create(ABaseSalary: Currency; ABonusPercentage: Double);
function CalculateGross: Currency;
function CalculateNet: Currency;
function IsEligibleForBonus: Boolean;
end;
//Cohesive class: HR responsibility
TEmployeeHrRecord = class
private
FHiredDate: TDate;
FVacationDaysLeft: Integer;
FPerformanceScore: Integer;
public
function GetYearsOfService: Integer;
function GetNextVacationDate: TDate;
function CalculateVacationPay(AGrossSalary: Currency): Currency;
end;
//Main entity — now just aggregates the parts
TEmployee = class
private
FPersonalData: TEmployeePersonalData;
FSalary: TEmployeeSalary;
FHrRecord: TEmployeeHrRecord;
public
constructor Create(AData: TEmployeePersonalData;
ASalary: TEmployeeSalary; AHr: TEmployeeHrRecord);
destructor Destroy; override;
property PersonalData: TEmployeePersonalData read FPersonalData;
property Salary: TEmployeeSalary read FSalary;
property HrRecord: TEmployeeHrRecord read FHrRecord;
end;---
**Detect:** More than 2 levels of `if..then..begin..end` nested.
**Before:**
function TBankService.Withdraw(AAccount: TAccount; AAmount: Currency): Boolean;
begin
Result := False;
if Assigned(AAccount) then
begin
if AAccount.IsActive then
begin
if AAmount > 0 then
begin
if AAccount.Balance >= AAmount then
begin
if not AAccount.IsBlocked then
begin
AAccount.Balance := AAccount.Balance - AAmount;
FRepository.Save(AAccount);
Result := True;
end;
end;
end;
end;
end;
end;**After:**
function TBankService.Withdraw(AAccount: TAccount; AAmount: Curren
An opinionated ecosystem of rules, skills and steerings to elevate Delphi development to state-of-the-art with Artificial Intelligence.
Repo: delphicleancode/delphi-spec-kit
Architectural, dependency injection and UI patterns for the ACBr Project (Commercial Automation Brazil) ecosystem in Delphi.
Pragmatic clean code standards for Delphi — concise, direct, no over-engineering
Delphi code review checklist — quality, security, performance, SOLID, memory
Good memory management practices, memory leak prevention and exception handling in Delphi
SOLID implementation patterns for Delphi projects — Repository, Service, Factory, Strategy with constructor injection and interfaces
Implementation of the 23 GoF (Gang of Four) patterns in Object Pascal / Delphi with interfaces, TInterfacedObject and SOLID principles. Covers Creational,…