Cuidado con los nombres demasiado abstractos o genéricos

04-07-2022

Por Carlos Blé Jurado

Una pista para encontrar diseños de software más sostenibles es buscar nombres descriptivos con un nivel de abstracción adecuado. Se busca que los nombres digan la verdad, que el código no de sorpresas. Que sean concretos y se ciñan al problema que se resuelve, aunque sin llegar a ser tan concretos que revelen detalles de implementación que produzcan un acoplamiento excesivo. Hay que buscar la simplicidad en el diseño, reducir el acoplamiento y maximizar la cohesión. La verdad es que diseñar software no es fácil. Prestar mucha mucha atención a los nombres es una táctica que nos permite descubrir muchos problemas de sostenibilidad en los diseños.

Evita usar nombres demasiado genéricos y abstractos. Reduce en lo posible las clases que parezcan "servicios", incluso si estás queriendo usar DDD. En lugar de esos "servicios", introduce modelos de dominio ricos que contengan tanto datos como funciones o métodos. Los nombres demasiado genéricos pueden identificarse a veces por sufijos:

  • *Service
  • *Handler
  • *Manager
  • *Transformer
  • *Converter
  • *Processor
  • *Engine
  • *Generator
  • *Driver
  • *Master

Puede que alguno esté bien usado y justificado, por ejemplo, si de verdad es un servicio de aplicación o un servicio de dominio en DDD, si de verdad hace falta que exista esa clase. En muchos casos he visto que se recurre a clases con sufijo Service o Repository, que no son servicios ni son repositorios. Lo que quiero decir no es que esta lista de palabras sea prohibida y te vayas a buscar otras todavía peores. Simplemente que lo tomes como una posible pista y pienses dos veces si la clase es necesaria.

Otra pista para pensar que una clase es innesaria, que le falta cohesión, es que se comporte como un mero artefacto middleman. Sería una clase que tiene dentro una instancia de otra (su dependencia), y que se limita a pasarle las llamadas que recibe sin hacer nada más en medio:

public class OrderTransformer {
private OrderService service;
/*...*/

public void saveOrder(Order order){
service.save(order);
}
/*...*/
}

Dependencias y responsabilidades

Otra pista para llegar a un diseño simple nos la da Kent Beck, que en una de sus reglas dice que es mejor tener el menor número de piezas. Hay que balancear esta regla con el principio de responsabilidad única, para no dejar que una clase tenga más de un motivo de cambio. Procura que las clases y artefactos tengan una sola responsabilidad, pero que tengan una, no media. Si no pueden hacer nada útil por sí mismas, quizá deberían fusionarse con otras.

Cuando utilices composición mediante inyección de dependencias, procura que una clase no tenga más de dos dependencias. Si la clase tiene tres o más dependencias, algo huele mal en ese diseño, tiene pinta de que falta cohesión en esa clase. Esta es otra heurística, no es una regla matemática, seguro que podremos encontrar algún caso con más de dos dependencias, que esté justificado.