Перегрузка метода. Вы можете злоупотреблять этим? - PullRequest
36 голосов
/ 29 октября 2008

Что лучше использовать при определении нескольких методов, которые возвращают одну и ту же форму данных с разными фильтрами? Явные имена методов или перегруженные методы?

Например. Если у меня есть некоторые продукты, и я вытаскиваю из базы данных

явный способ:

public List<Product> GetProduct(int productId) {    // return a List    }
public List<Product> GetProductByCategory(Category category) {    // return a List    }
public List<Product> GetProductByName(string Name ) {    // return a List    }

перегружен путь:

public List<Product> GetProducts() {    // return a List of all products    }
public List<Product> GetProducts(Category category) { // return a List by Category }
public List<Product> GetProducts(string searchString ) { // return a List by search string }

Я понимаю, что вы можете столкнуться с проблемой подобных подписей , но если вы передаете объекты вместо базовых типов (string, int, char, DateTime и т. Д.), Это будет меньше проблем , Итак ... это хорошая идея перегрузить метод , чтобы уменьшить количество методов, которые у вас есть, и для ясности, или должен каждый метод , который фильтрует данные по-разному имеют другое имя метода ?

Ответы [ 16 ]

1 голос
/ 29 октября 2008

Да, вы можете злоупотреблять им, однако вот еще одна концепция, которая может помочь контролировать его использование ...

Если вы используете .Net 3.5+ и вам нужно применить несколько фильтров, вам, вероятно, лучше использовать IQueryable и цепочку, т.е.

GetQuery<Type>().ApplyCategoryFilter(category).ApplyProductNameFilter(productName);

Таким образом, вы можете многократно использовать логику фильтрации везде, где вам это нужно.

public static IQueryable<T> ApplyXYZFilter(this IQueryable<T> query, string filter)
{
     return query.Where(XYZ => XYZ == filter);
} 
0 голосов
/ 17 мая 2012

Как насчет

public IList<Product> GetProducts() { /* Return all. */}

public IList<Product> GetProductBy(int productId) {...}
public IList<Product> GetProductBy(Category category) {...}
public IList<Product> GetProductBy(string Name ) {...}

И так далее?

0 голосов
/ 14 января 2009

Я фанат "явного" способа: дать каждой функции свое имя. Я даже рефакторил код, в котором раньше было множество Add(...) функций, до AddRecord(const Record&), AddCell(const Cell&) и т. Д.

Я думаю, что это помогает избежать путаницы, непреднамеренных приведений (по крайней мере, в C ++) и предупреждений компилятора, а также улучшает ясность.

Может быть, в некоторых случаях вам нужна другая стратегия. Я еще не встречал ни одного.

0 голосов
/ 30 октября 2008

да, вы можете злоупотреблять этим. В вашем примере может показаться, что первый и третий, вероятно, вернут один элемент, а второй вернет несколько. Если это правильно, то я бы назвал первый и третий GetProduct и второй GetProducts или GetProductList

если это не так, и все три возвращают несколько (например, если вы передаете ему productID 5, он возвращает любые элементы с 5 в productid или возвращает любые элементы с строковым параметром в его имени), тогда я бы вызвал все три GetProducts или GetProductList и переопределить их все.

В любом случае имя должно отражать то, что делает функция, поэтому вызов его GetProduct (в единственном числе), когда он возвращает список продуктов, не дает правильного имени функции. IMNSHO

0 голосов
/ 30 октября 2008

Перегрузка желательна, полиморфное поведение. Это помогает программисту запомнить имя метода. Если явный избыточен с параметром типа, то это плохо. Если параметр типа не подразумевает того, что делает метод, тогда явное начало иметь смысл.

В вашем примере getProductByName - единственный случай, когда явное объяснение может иметь смысл, так как вы можете захотеть получить продукт по какой-то другой строке. Эта проблема была вызвана неоднозначностью примитивных типов; getProduct (имя n) может быть лучшим решением для перегрузки в некоторых случаях.

0 голосов
/ 30 октября 2008

Вы можете использовать Перегрузку столько, сколько хотите. Также с точки зрения передового опыта рекомендуется использовать перегрузку, если вы пытаетесь выполнить ту же «операцию» (целостно) над данными. Например. getProduct ()

Кроме того, если вы видите Java API, перегрузка везде. Вы не найдете большего одобрения, чем это.

...