Sí, la sobrecarga puede sobreutilizarse fácilmente.
He descubierto que la clave para determinar si una sobrecarga está justificada o no es considerar a la audiencia, no al compilador, sino al programador de mantenimiento que vendrá en semanas/meses/años y tiene que entender lo que el código está tratando de lograr
Un nombre de método simple como GetProducts() es claro y comprensible, pero no deja mucho que decir.
En muchos casos, si el parámetro pasado a GetProducts() está bien nombrado, el técnico de mantenimiento podrá determinar qué hace la sobrecarga, pero eso depende de una buena disciplina de nomenclatura en el punto de uso, que puede hacer cumplir. Lo que puede hacer cumplir es el nombre del método que están llamando.
La pauta que sigo es sobrecargar solo los métodos si son intercambiables, si hacen lo mismo. De esta forma, no me importa qué versión invoca el consumidor de mi clase, ya que son equivalentes.
Para ilustrar, con mucho gusto haría uso de sobrecargas por un método DeleteFile():
void DeleteFile(string filePath);
void DeleteFile(FileInfo file);
void DeleteFile(DirectoryInfo directory, string fileName);
Sin embargo, para sus ejemplos, que haría uso de nombres distintos:
public IList<Product> GetProductById(int productId) {...}
public IList<Product> GetProductByCategory(Category category) {...}
public IList<Product> GetProductByName(string Name) {...}
Tener la plena names hace que el código sea más explícito para el tipo de mantenimiento (que bien podría ser yo). Evita problemas con que tienen colisiones firma:
// No collisions, even though both methods take int parameters
public IList<Employee> GetEmployeesBySupervisor(int supervisorId);
public IList<Employee> GetEmployeesByDepartment(int departmentId);
También existe la posibilidad de introducir una sobrecarga para cada propósito:
// Examples for GetEmployees
public IList<Employee> GetEmployeesBySupervisor(int supervisorId);
public IList<Employee> GetEmployeesBySupervisor(Supervisor supervisor);
public IList<Employee> GetEmployeesBySupervisor(Person supervisor);
public IList<Employee> GetEmployeesByDepartment(int departmentId);
public IList<Employee> GetEmployeesByDepartment(Department department);
// Examples for GetProduct
public IList<Product> GetProductById(int productId) {...}
public IList<Product> GetProductById(params int[] productId) {...}
public IList<Product> GetProductByCategory(Category category) {...}
public IList<Product> GetProductByCategory(IEnumerable<Category> category) {...}
public IList<Product> GetProductByCategory(params Category[] category) {...}
Código es leer mucho más de lo que está escrito - incluso si nunca llega Volviendo al código después de la verificación inicial en el control de la fuente, todavía leerás esa línea de código un par de docenas de veces mientras escribes el código que sigue.
Por último, a menos que esté escribiendo código descartable, debe permitir que otras personas llamen a su código desde otros idiomas. Parece que la mayoría de los sistemas empresariales terminan estando en producción mucho más allá de su uso por fecha. Puede ser que el código que consume tu clase en 2016 termine escrito en VB.NET, C# 6.0, F # o algo completamente nuevo que aún no se haya inventado. Es posible que el idioma no admita sobrecargas.
Publicación muy agradable con muchos ejemplos. ¡Gracias! – Armstrongest
+1 ¡sí, publicación realmente útil, aplausos! – andy
+1 excelente consejo, de acuerdo de todo corazón. La sobrecarga de métodos sin una necesidad real es malvada. Añadiría que (al menos en Java) es aún más malo en setters – leonbloy