El Clean Code (Código Limpio) es una filosofía de desarrollo que busca escribir código que sea no solo funcional, sino también legible, mantenible y escalable. En el contexto de Delphi, aplicar estos principios es esencial para garantizar que el software desarrollado sea de alta calidad y fácil de gestionar a lo largo del tiempo.
Usar nombres como x
, temp
o data
no comunica el propósito real de la variable o función. Esto dificulta la comprensión del código y su mantenimiento.
// Ejemplo Incorrecto
var
a: Integer;
// Ejemplo Correcto
var
TotalVentas: Integer;
Las funciones que realizan múltiples tareas son difíciles de leer, probar y mantener. Es mejor dividirlas en funciones más pequeñas y específicas.
// Ejemplo Incorrecto
procedure ProcesarDatos;
begin
ValidarDatos;
CalcularTotales;
GuardarEnBaseDeDatos;
end;
// Ejemplo Correcto
procedure ValidarDatos;
begin
// Implementación
end;
procedure CalcularTotales;
begin
// Implementación
end;
procedure GuardarEnBaseDeDatos;
begin
// Implementación
end;
Repetir el mismo bloque de código en múltiples lugares aumenta la posibilidad de errores y complica el mantenimiento. Utiliza funciones o procedimientos reutilizables.
// Ejemplo Incorrecto
procedure ValidarEntrada1;
begin
// Validación similar
end;
procedure ValidarEntrada2;
begin
// Validación similar
end;
// Ejemplo Correcto
procedure ValidarEntrada;
begin
// Validación única
end;
El código debe ser lo suficientemente claro para no necesitar explicaciones adicionales. Los comentarios redundantes pueden distraer y enmascarar problemas reales.
// Ejemplo Incorrecto
// Incrementar contador en 1
Contador := Contador + 1;
// Ejemplo Correcto
Contador := Contador + 1;
Cuando las clases o módulos dependen demasiado unos de otros, se dificulta su mantenimiento y prueba. Es preferible mantener una baja dependencia entre los componentes.
// Ejemplo Incorrecto
type
TLogicaNegocio = class
procedure Ejecutar;
end;
procedure TLogicaNegocio.Ejecutar;
begin
// Lógica de negocio mezclada con la interfaz de usuario
Formulario.ShowMessage('Ejecutado');
end;
// Ejemplo Correcto
type
TLogicaNegocio = class
procedure Ejecutar;
end;
procedure TLogicaNegocio.Ejecutar;
begin
// Solo lógica de negocio
end;
// En la interfaz de usuario
procedure TFormulario.BotonClick(Sender: TObject);
begin
LogicaNegocio.Ejecutar;
ShowMessage('Ejecutado');
end;
Dejar excepciones sin manejar o usar bloques try..except
vacíos puede ocultar errores críticos, dificultando la detección y resolución de problemas.
// Ejemplo Incorrecto
try
// Código
except
end;
// Ejemplo Correcto
try
// Código
except
on E: Exception do
LogError(E.Message);
end;
Elegir nombres que describan claramente el propósito de variables, funciones y clases mejora la legibilidad y facilita la comprensión del código.
// Ejemplo
function CalcularImpuesto(Ventas: Double): Double;
begin
// Implementación
end;
Dividir el código en funciones más pequeñas y específicas mejora la legibilidad y facilita las pruebas unitarias.
// Ejemplo de función pequeña y específica
function CalcularTotal(Ventas: TList<Venta>): Double;
begin
// Implementación
end;
Reutilizar código mediante funciones o procedimientos comunes reduce la redundancia y mejora la eficiencia del desarrollo.
// Ejemplo Incorrecto: Código repetido
procedure FormatearFecha1;
begin
// Formateo
end;
procedure FormatearFecha2;
begin
// Formateo
end;
// Ejemplo Correcto: Función reutilizable
function FormatearFecha(Fecha: TDateTime): string;
begin
Result := FormatDateTime('dd/mm/yyyy', Fecha);
end;
Las pruebas unitarias garantizan que el código funcione correctamente y facilitan la detección de errores durante el desarrollo.
// Ejemplo de prueba unitaria usando DUnitX
uses
DUnitX.TestFramework;
type
[TestFixture]
TTestCustomer = class
public
[Test]
procedure TestEsMayorDeEdad;
end;
procedure TTestCustomer.TestEsMayorDeEdad;
var
Cliente: TCliente;
begin
Cliente := TCliente.Create('Juan', 20);
try
Assert.IsTrue(Cliente.EsMayorDeEdad);
finally
Cliente.Free;
end;
end;
Mantener la lógica de negocio separada de la interfaz de usuario facilita el mantenimiento y las pruebas, además de mejorar la modularidad del código.
// Uso del patrón MVP (Model-View-Presenter)
type
IClienteVista = interface
procedure MostrarMensaje(Mensaje: string);
end;
TClientePresentador = class
private
FVista: IClienteVista;
public
constructor Create(Vista: IClienteVista);
procedure ProcesarCliente;
end;
constructor TClientePresentador.Create(Vista: IClienteVista);
begin
FVista := Vista;
end;
procedure TClientePresentador.ProcesarCliente;
begin
// Lógica de negocio
FVista.MostrarMensaje('Cliente Procesado');
end;
Escribe comentarios únicamente cuando el código no sea autoexplicativo, enfocándote en explicar el "por qué" más que el "qué".
// Ejemplo Incorrecto
// Incrementa contador
Inc(Counter);
// Ejemplo Correcto
// Compensación por límite de buffer circular
Inc(Counter);
Captura excepciones específicas y proporciona mensajes claros para facilitar la resolución de errores.
// Ejemplo
try
Customer.SaveToDatabase;
except
on E: EDatabaseError do
ShowMessage('Error al guardar en la base de datos: ' + E.Message);
end;
Adoptar un estilo de codificación consistente mejora la legibilidad y facilita la colaboración entre desarrolladores.
// Uso de prefijos
type
TCliente = class
private
FNombre: string;
public
procedure SetNombre(Value: string);
end;
Revisar y mejorar el código existente ayuda a eliminar la deuda técnica y a mantener la calidad del software.
// Refactorización para simplificar condiciones
if (Edad >= 18) and (EstadoCivil = 'Soltero') then
// Acción
Herramientas como Pascal Analyzer o Delphi Lint ayudan a identificar problemas de calidad en el código, facilitando su mejora continua.
Demostración de una clase limpia y bien estructurada en Delphi:
// Definición de la clase TCliente
type
TCliente = class
private
FNombre: string;
FEdad: Integer;
public
constructor Create(Nombre: string; Edad: Integer);
function EsMayorDeEdad: Boolean;
end;
implementation
constructor TCliente.Create(Nombre: string; Edad: Integer);
begin
FNombre := Nombre;
FEdad := Edad;
end;
function TCliente.EsMayorDeEdad: Boolean;
begin
Result := FEdad >= 18;
end;
En este ejemplo:
EsMayorDeEdad
solo verifica si la edad del cliente es mayor o igual a 18.F
para campos privados y T
para tipos de clases.Aplicar los principios de Clean Code en Delphi no solo mejora la calidad del software, sino que también facilita su mantenimiento y escalabilidad a largo plazo. Al seguir las mejores prácticas y evitar errores comunes, los desarrolladores pueden crear aplicaciones robustas y eficientes que cumplen con los estándares de la industria.