What\'s better practice when defining several methods that return the same shape of data with different filters? Explicit method names or overloaded methods?
For exa
Another option is to use a Query object to build the "WHERE Clause". So you would have only one method like this:
public List<Product> GetProducts(Query query)
The Query object contains the condidition expressed in an Object Oriented way. The GetProducts obtain the query by "parsing" the Query object.
http://martinfowler.com/eaaCatalog/queryObject.html
I like overloading my methods so that later on in the intellisense I don't have a million of the same method. And it seems more logical to me to have it just overloaded instead of having it named differently a dozen times.
I have seen overloading overused when you have only subtle differences in the arguments to the method. For example:
public List<Product> GetProduct(int productId) { // return a List }
public List<Product> GetProduct(int productId, int ownerId ) { // return a List }
public List<Product> GetProduct(int productId, int vendorId, boolean printInvoice) { // return a List }
In my small example, it quickly becomes unclear if the second int
argument should be the owner or customer id.
The point of overloading to to ease the learning curve of someone using your code... and to allow you to use naming schemes that inform the user as to what the method does.
If you have ten different methods that all return a collection of employees, Then generating ten different names, (Especially if they start with different letters!) causes them to appear as multiple entries in your users' intellisense drop down, extending the length of the drop down, and hiding the distinction between the set of ten methods that all return an employee collection, and whatever other methods are in your class...
Think about what is already enforced by the .Net framework for, say constructors, and indexers... They are all forced to have the same name, and you can only create multiples by overloading them...
If you overload them, they will all appear as one, with their disparate signatures and comments off to tthe side.
You should not overload two methods if they perform different or unrelated functions...
As to the confusion that can exist when you want to overload two methods with the same signature by type as in
public List<Employee> GetEmployees(int supervisorId);
public List<Employee> GetEmployees(int departmentId); // Not Allowed !!
Well you can create separate types as wrappers for the offending core type to distinguish the signatures..
public struct EmployeeId
{
private int empId;
public int EmployeeId { get { return empId; } set { empId = value; } }
public EmployeeId(int employeId) { empId = employeeId; }
}
public struct DepartmentId
{
// analogous content
}
// Now it's fine, as the parameters are defined as distinct types...
public List<Employee> GetEmployees(EmployeeId supervisorId);
public List<Employee> GetEmployees(DepartmentId departmentId);
Overloading is desirable polymorphic behavior. It helps the human programmer remember the method name. If explicit is redundant with the type parameter, then it is bad. If the type parameter does not imply what the method is doing, then explicit starts to make sense.
In your example, getProductByName is the only case where explicit might make sense, since you might want to get product by some other string. This problem was caused by the ambiguity of primitive types; getProduct(Name n) might be a better overload solution in some cases.
How about
public IList<Product> GetProducts() { /* Return all. */}
public IList<Product> GetProductBy(int productId) {...}
public IList<Product> GetProductBy(Category category) {...}
public IList<Product> GetProductBy(string Name ) {...}
And so on?