best_practice2.6022437_std

Uno de los mayores problemas a la hora de mantener el código de una aplicación es la legibilidad del mismo. En muchas ocasiones, la primera impresión que tenemos al ver un fragmento de código es: ¡Pero esto qué hace? ¡Qué se había fumado quién escribió esto? Y, lo peor de todo, es que en la mayoría de los casos se trata de…¡nuestro propio código! Al que ni siquiera reconocemos un tiempo después…

Sobre este tema han corrido grandes ríos de tinta. Nosotros no queremos dar más vueltas al asunto, sino proponeros una pequeña estrategia para hacer el código más legible: utilizar métodos extensores.

Desde que aparecieran en la versión 3.5 del Framework de .Net, los métodos extensores han ido ganando fuerza y cada vez son más habituales en las aplicaciones .Net. Su utilización aporta sobretodo una técnica fácil, sencilla y para toda la familia de añadir funcionalidad a clases de manera extremadamente flexible, pero además pueden utilizarse para mejorar la legibilidad del código.

Tenemos muchos ejemplos de ello, aquí os ponemos un par de ellos que seguro que conocéis: los métodos extensores de LINQ y Fluent Assertions:

 

  • Métodos extensores de LINQ contra LINQ puro:

 [code javascript]// Pure LinQ

var users = from user in collection
            where user.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase)
            orderby user.Type descending 
            select user;
var usersList = users.ToList();

// LinQ Extensions
var usersLists = collection.Where(user => user.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase))
                           .OrderByDescending(user => user.Type)
                           .ToList();[/code]

 

  • Fluent Assertions contra los tradicionales métodos Assert:
 [code javascript]// Traditional Assert
Assert.AreEqual(expectedValue, result);

// Fluent Assertions
result.Should().Be(expectedValue); [/code]

Basándonos en los métodos extensores con los que trabajamos día a día, como los ejemplos anteriores, lo lógico es que al cabo de un tiempo empecemos a ver el códigoque escribimos con otros ojos. Y nos empiece a resultar un poco extraño código tan habitual como el siguiente:

  [code javascript]if (entity == null)

{
    throw ArgumentNullException("La entidad no puede ser nula."):
}

if (value < 0)
{
    throw ArgumentException("El valor tiene que ser mayor que 0."):
}

if (string.IsNullOrWhiteSpace(email))
{
   throw ArgumentNullException("El e-mail no puede ser nulo, estar vacío o ser una cadena de caracteres vacía.");
}

const string emailExpresion = "\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*";
if (!Regex.IsMatch(email, expresion))
{
   throw FormatException("El e-mail no tiene un formato correcto.");
} [/code]

 

Es muy habitual llenar el código con este tipo de validaciones. Pero al realizarlo de este modo ocupamos muchas líneas de código innecesariamente, con lo que perdemos legibilidad.

¿Por qué no usar métodos extensores para hacerlo más legible?

Efectivamente, ¿por qué no? Hacerlo es muy sencillo, encapsulamos el mismo códigoen método extensores cuya firma describa claramente lo que hacen, y de esta manera ganaremos en legibilidad y, en este caso, también en reutilización de código.

  [code javascript]public static void CantBeNull<T>(this T entity)

{
    if (entity == null)
    {
        throw ArgumentNullException("La entidad no puede ser nula.");
    }
}

public static void MustBeGreaterThan(this int value, int limit)
{
    if (value < limit)
    {
        string message = string.Format("El valor no puede ser menor que {0}.", limit);
        throw ArgumentException(message);
    }
}

public static void CantBeNullOrWhiteSpace(this string text)
{
    if (string.IsNullOrWhiteSpace(text))
    {        
        throw ArgumentNullException("Esta cadena de caracteres no puede ser nula, estar vacía o ser sólo espacios en blanco");
    }
}

public static void MustBeAnEmailAddress(this string email)
{
    email.CantBeNullOrWhiteSpace();

    const string emailExpresion = "\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*";
    if (!Regex.IsMatch(email, emailExpression)
    {        
        throw FormatException("El e-mail no tiene un formato correcto.");
    }
} [/code]



 

Ahora no tenemos más que utilizar este código para realizar las validaciones anteriores, y tendremos un código mucho más legible.

  [code javascript]

entity.CantBeNull();

value.MustBeGreaterThan(0);

email.MustBeAnEmailAddress(); [/code]

 

Esperamos que esta os parezca una buena idea, ¡a nosotros nos la parece! Seguro que cuando empecéis a darle y utilizar esta sencilla técnica, vuestro código se vuelve mucho más legible y fácil de mantener. ¡Y seguro que se os ocurren muchas más aplicaciones!