Clean Code #2: Firmas Pobres

Hasta ahora vimos nombres pobres y las mejores prácticas para corregirlo. Ahora es el momento de firmas pobres en los métodos. Veamos.

Firmas pobres en métodos

Básicamente estamos presencia de una firma pobre cuando tenemos métodos que no son significativos y que no dicen realmente cual es su objetivo, por ejemplo:

Brown GetProduct(int airplane);

Como vemos, este método dice GetProduct, pero recibe como parámetro un airplane y devuelve un objeto Brown, no es un objeto Product…. Realmente, no se entiende el objetivo de este método y es bastante confuso.

Veamos otro método:

void Parse(int command);

Tenemos un método que recibe un tipo de dato int y no nos devuelve nada. ¿Qué tiene de malo este método? Típicamente los métodos llamados Parse reciben un string y devuelven un objeto. En este caso, al existir métodos con un significado, nos conviene respetarlo. Lo usaremos  de la siguiente forma:

int Parse(string command);

Veamos más ejemplos:

public class PoorMethodSignatures{

    public void Run(){

        var productService = new ProductService();

        var product = productService.GetProduct("productName", "description", true);

        var anotherProduct = productService.GetProduct("productName", null, false);

    }

}

Vemos que tenemos un método que se llama Run, dentro, se crea un objeto ProductService. Luego, se invoca al método GetProduct que recibe 3 parámetros, “productName”, “description” y un flag true. En la siguiente línea, vemos que se invoca nuevamente el mismo método pero, el segundo parámetro es null y el tercero es falso.

Estamos obligados a ver la implementación del método porque no nos dice que hace. Veamos la implementación:

public class ProductService

{

    private ProductDbContext _dbContext = new ProductDbContext();

    public Product GetProduct(string productName, string description, bool onlyByName){

        if(onlyByName){

            var product = _dbContext.Products

                                .SingleOrDefault(p => p.ProductName == productName 

                                    && p.Description == description);

            if(product != null)

                product.UpdateCreated = DateTime.Now;

            return product;

        }else{

            var product = _dbContext.Products

                                .SingleOrDefault(p => p.ProductName == productName); 

            return product;

        }

    }

}

El método, dependiendo del tercer valor, irá por un camino u otro. Si es true, buscará en la base de datos por nombre del producto y la descripción, si lo encuentra, cambiará el valor de la propiedad UpdateCreated y devolverá en objeto producto. 

En caso de que parámetro onlyByName sea false, lo buscara por el parámetro productName y nos devolverá el producto.

Algo que debemos tener en cuenta, casi siempre, parámetros del tipo boolean en las firmas de los métodos son Code Smells. Nos alerta de que el método, seguramente, hace diferentes cosas dependiendo de este parámetro. Si tenemos muchos parámetros boolean en el método, esto hará más complejo nuestro código teniendo diferentes combinaciones de estos parámetros para resolver situaciones.

Veamos un mejor camino. Primero separaremos está el código donde se busca por los 3 parámetros. Crearemos el método GetProductByNameByDescription() para no tener más el parámetro booleano , volverlo mucho más expresivo y que denote una intención.

public Product GetProductByNameByDescription(string name, string description){

        var product = _dbContext.Products

                                        .SingleOrDefault(p => p.ProductName == name 

                                            && p.Description == description);

        if(product != null)

            product.UpdateCreated = DateTime.Now;

        return product;

    }

Todavía nos queda resolver la siguiente línea de código

var anotherProduct = productService.GetProduct(“productname”, null, false);

Ahora podemos eliminar los parámetros de descripción y el booleano. Estos no son utilizados para el método que nos queda. Queda de esta manera:

public Product GetProduct(string productName){

        var product = _dbContext.Products

                                .SingleOrDefault(p => p.ProductName == productName); 

        return product;

    }

Para concluir, nuestros métodos quedan más limpios, más pequeños y más mantenibles. Cualquier persona que lee nuestro código sabrá qué intenciones tiene y no necesitaran ver la implementación para saber qué hacen.

public class PoorMethodSignatures{

    public void Run(){

        var productService = new ProductService();

        var product = productService.GetProductByNameByDescription("productname", "description");

        var anotherProduct = productService.GetProduct("productname);

    }

}

Conclusión

Siempre debemos tener en cuenta y validarlos más de una vez los siguientes puntos:

  • Chequear que devuelvan un solo tipo.
  • Chequear el nombre del método.
  • Chequear los parámetros.

En próximos posts veremos más trucos para mejorar y limpiar nuestro código.

0 0 votos
Valora la Publicación
Suscribirse
Notificación de
guest
0 Comentarios
Feedback en línea
Ver todos los Comentarios

Comentarios Recientes

0
Nos encantaría conocer tu opinión: ¡comenta!x
Ir a la barra de herramientas