En el desarrollo de software, dos principios fundamentales que a menudo se discuten son DRY (Don’t Repeat Yourself) y DAMP (Descriptive and Meaningful Phrases). Ambos buscan mejorar la calidad del código, pero lo hacen de maneras diferentes y, en ocasiones, pueden parecer contradictorios. Sin embargo, al comprender cómo y cuándo aplicarlos, podemos lograr un código limpio, mantenible y fácil de entender.
¿Qué es DRY?
DRY (Don’t Repeat Yourself) es un principio ampliamente conocido en el desarrollo de software que aboga por la eliminación de la duplicación de código. La idea central es que cada pieza de lógica o conocimiento debe tener una única representación en el sistema. Esto reduce el riesgo de inconsistencias y facilita el mantenimiento, ya que cualquier cambio necesario solo debe hacerse en un lugar.
Ejemplos de cómo aplicar DRY en C# incluyen:
- La creación de métodos reutilizables en lugar de copiar y pegar lógica.
- La utilización de constantes para valores repetidos.
- La implementación de clases base o interfaces compartidas.
¿Qué es DAMP?
DAMP (Descriptive and Meaningful Phrases), por otro lado, prioriza la claridad y legibilidad del código. Este principio sugiere que el código debe ser descriptivo y contener frases significativas que faciliten su comprensión. La meta es que cualquier desarrollador que lea el código pueda entender su propósito y funcionamiento sin necesidad de documentación extensa.
En C#, esto se logra mediante:
- Nombres de métodos y variables que describen claramente su propósito.
- Uso de comentarios explicativos cuando sea necesario para aclarar la lógica.
- Estructura de código que facilite la lectura y el mantenimiento.
¿Contradicción o Complemento?
A primera vista, DRY y DAMP pueden parecer contradictorios. DRY busca reducir la redundancia, mientras que DAMP sugiere que la repetición puede ser aceptable si mejora la claridad. Sin embargo, ambos principios pueden coexistir y complementarse. La clave está en encontrar un equilibrio adecuado.
Por ejemplo, DRY nos impulsa a abstraer lógica compartida en un método reutilizable, mientras que DAMP nos recuerda que ese método debe ser claramente comprensible y tener un nombre descriptivo, incluso si eso significa repetir cierta lógica en diferentes contextos para mejorar la legibilidad.
Caso Práctico en C#
Imaginemos que estamos desarrollando una aplicación que envía notificaciones por Email y SMS, y queremos escribir pruebas unitarias para asegurarnos de que se envían correctamente.
// Sin Aplicar DRY ni DAMP
[TestClass]
public class NotifierTests
{
[TestMethod]
public void TestSendEmailNotification()
{
var notifier = new Notifier();
var result = notifier.SendEmail("test@example.com", "Test Subject", "Test Message");
Assert.AreEqual("Email sent to test@example.com", result);
}
[TestMethod]
public void TestSendSmsNotification()
{
var notifier = new Notifier();
var result = notifier.SendSms("1234567890", "Test Message");
Assert.AreEqual("SMS sent to 1234567890", result);
}
}
// Aplicando DRY
[TestClass]
public class NotifierTests
{
private Notifier SetupNotifier()
{
return new Notifier();
}
[TestMethod]
public void TestSendEmailNotification()
{
var notifier = SetupNotifier();
var result = notifier.SendEmail("test@example.com", "Test Subject", "Test Message");
Assert.AreEqual("Email sent to test@example.com", result);
}
[TestMethod]
public void TestSendSmsNotification()
{
var notifier = SetupNotifier();
var result = notifier.SendSms("1234567890", "Test Message");
Assert.AreEqual("SMS sent to 1234567890", result);
}
}
// Aplicando DAMP
[TestClass]
public class NotifierTests
{
private Notifier SetupNotifier()
{
return new Notifier();
}
[TestMethod]
public void SendEmailNotification_ShouldSendEmailToCorrectAddress()
{
var notifier = SetupNotifier();
var result = notifier.SendEmail("test@example.com", "Test Subject", "Test Message");
Assert.AreEqual("Email sent to test@example.com", result,
"The email was not sent to the expected address.");
}
[TestMethod]
public void SendSmsNotification_ShouldSendSmsToCorrectNumber()
{
var notifier = SetupNotifier();
var result = notifier.SendSms("1234567890", "Test Message");
Assert.AreEqual("SMS sent to 1234567890", result,
"The SMS was not sent to the expected number.");
}
}
¿Qué logramos con DRY?
- Evitamos la duplicación de código al reutilizar el método
SetupNotifier
. - Si en el futuro la creación de
Notifier
cambia, solo necesitamos actualizarlo en un lugar.
¿Qué logramos con DAMP?
- Nombres de métodos más descriptivos, indicando explícitamente lo que se está probando.
- Mensajes de aserción que proporcionan contexto en caso de fallo, facilitando la depuración.
- Mayor claridad y legibilidad del propósito de cada prueba.
Reflexión Final
La clave está en encontrar el equilibrio adecuado. Un exceso de DRY puede llevar a un código demasiado abstracto y difícil de entender, mientras que ignorar DRY en favor de DAMP puede resultar en redundancia innecesaria. Al final del día, el objetivo es escribir código limpio, mantenible y fácil de entender, y aplicar estos principios en conjunto es la mejor manera de lograrlo.
Por eso he utilizado el ejemplo de los tests. En este contexto, suelo priorizar DAMP sobre DRY, y hay una razón para ello. Cuando reviso una Pull Request, me importa mucho más que los tests sean claros y fáciles de leer a que sean extremadamente reutilizables o abstractos. Prefiero que cada prueba sea explícita y descriptiva, incluso si eso significa repetir cierta configuración o lógica. Esto facilita la comprensión de qué se está probando y por qué, lo que hace que la revisión y el mantenimiento sean mucho más sencillos.
Ahora bien, esto no significa que haga una distinción estricta entre código productivo y código de pruebas. No se trata de aplicar DRY o DAMP de manera exclusiva, sino de balancear ambos principios de acuerdo con la situación. La clave está en evaluar cuándo la reutilización realmente aporta valor y cuándo la claridad es más importante. Sin embargo, en los tests, la legibilidad y la intención clara son mi prioridad. Prefiero repetir un poco de código antes que sacrificar la comprensión de lo que se está verificando.
Nota final: Como siempre os digo, cuando me toca repetir lo mismo varias veces, al final escribo un artículo. ¿Esto es DRY o es DAMP? ¿O quizás es una combinación de ambos? La realidad es que este artículo existe precisamente para reducir la repetición de explicaciones (DRY), pero al mismo tiempo está escrito de manera clara y descriptiva para asegurar que todos puedan entenderlo (DAMP). Una vez más, ¡el equilibrio lo es todo!