Предположим интерфейс, содержащий эти методы:
Car find(long id);
List<Car> find(String model);
Лучше переименовать их так?
Car findById(long id);
List findByModel(String model);
Действительно, любому разработчику, использующему этот API, не нужно смотреть на интерфейс, чтобы узнать возможные аргументы начальных find()
методов.
Поэтому мой вопрос носит более общий характер: в чем преимущество использования перегруженных методов в коде, поскольку они снижают читабельность?
Ответы:
Это относительно небольшая проблема по сравнению со многими другими методами плохой читабельности, к которым вы могли бы быть восприимчивы, поэтому я бы сказал, что в основном это вопрос вкуса, как вы называете свои методы.
С учетом сказанного, если вы собираетесь что-то с этим делать, я бы следовал этой практике:
Перегрузка, если ...
Методы подчиняются почти одному и тому же контракту, но просто работают с другим вводом данных (представьте себе телефонного оператора, который может искать вашу учетную запись по вашему личному налоговому номеру, номеру вашей учетной записи или вашему имени и дате рождения). Это включает в себя возврат того же типа вывода .
Используйте другое имя, если ...
Методы делают существенно разные вещи или возвращают разные результаты (как в вашем случае). Вы можете рассмотреть возможность использования другого имени, если один обращается к базе данных, а другой - нет.
Кроме того, если возвращаемый тип отличается, я бы также изменил глагол, чтобы указать, что:
источник
Я бы рекомендовал использовать другое имя в каждом случае. Возможно, что в будущем вы захотите добавить другой метод, скажем
List<Car> findByMake(String make)
, в отличие отList<Car> findByModel(String model)
. Так внезапно, звонить всеfind
перестает иметь смысл. Ваши методы также с меньшей вероятностью будут непреднамеренно использованы неправильно, если их имена дают больше информации о том, как их следует использовать.источник
find(Make val)
иfind(Model val)
. Тогда удобные методы, такие какfindByMake(String val)
, будут намного более ясными, что они фактически делают. В конце концов, aString
не является ни маркой, ни моделью, поэтому метод должен объяснить, что он на самом деле делает.Если вы переименуете метод, он больше не будет перегружен. Сама по себе перегрузка не обязательно делает код менее читабельным, однако она может усложнить реализацию, если синтаксис не ясен.
Многие языки используют перегрузку методов как средство представления интерфейса функциональности, где параметры могут быть необязательными и подразумеваются значения по умолчанию для необязательных параметров. Это особенно верно для языков, которые не поддерживают синтаксис параметров по умолчанию в объявлении метода.
Так делаем это:
избавляет вас от этого:
Что касается того, что является более читабельным, то это действительно сводится к вам. Лично я предпочитаю второй вариант, особенно когда список параметров становится немного длиннее, но я полагаю, что это не имеет большого значения, если вы последовательны в своем API.
Трудность с перегрузкой возникает тогда, когда вы хотите, чтобы функции выполняли, по сути, одно и то же, и когда вы хотите, чтобы списки параметров были одинаковыми, но типы возвращаемых данных были разными. Большинство языков не знают, как различать два метода, названных одинаково, но с разными типами возврата. На этом этапе вам нужно подумать об использовании обобщений, изменении интерфейса параметров или переименовании одного из ваших методов, чтобы указать разницу в типе возвращаемого значения. Именно здесь удобочитаемость может стать большой проблемой, если вы не остановитесь на простой и понятной схеме именования для решения подобных ситуаций.
Присвоение имен перегруженных методов
GetSomething()
иGetSomethingEx()
не будет много говорить о том, что различия между вашими методами, особенно если она является возвращаемые типы, которые только различия между ними. С другой стороны,GetSomethingAsInt()
иGetSomethingAsString()
расскажем вам немного больше о том, что делают методы, и хотя они не являются строго перегрузочными, они указывают на то, что оба метода выполняют схожие функции, но возвращают разные типы значений. Я знаю, что есть другие способы, которыми вы могли бы называть методы, однако для иллюстрации, эти грубые примеры должны подойти.В примере с OP переименование не является строго необходимым, поскольку параметры метода различны, однако это немного упрощает наименование метода. В конце концов, все сводится к типу интерфейса, который вы хотите представить своим пользователям. Решение о том, не следует ли перегружать, не должно приниматься исключительно на основании вашего собственного восприятия читабельности. Перегрузка методов может, например, упростить интерфейс API и уменьшить количество методов, которые разработчик, возможно, должен запомнить, с другой стороны, он может запутать интерфейс до такой степени, которая затем требует, чтобы разработчик прочитал документацию метода, чтобы понять, какая форма метода для использования, в то время как наличие ряда аналогично, но описательно названных методов может сделать это более очевидным, просто читая имя метода относительно его цели.
источник
Избегайте перегрузки, если методы возвращают одно и то же и следуют одному и тому же контракту. Перегрузка освобождает вызывающий код от ненужной фиксации к типу параметра.
Предположим, что вызывающая функция получает поисковый запрос в качестве параметра и выполняет некоторую другую обработку до и / или после вызова
find
.Если вы хотите изменить тип этого запроса по какой-либо причине в будущем (например, от простой строки идентификатора до полнофункционального объекта запроса), вы можете внести это изменение в вызывающую функцию, просто изменив сигнатуру функции. принять новый тип параметра, не беспокоясь об изменении метода, который он вызывает в вашем классе.
Если вы реализуете
findById
иfindByQueryObject
отдельно, вам придется выслеживать каждый вызов, чтобы внести это изменение. В примере я изменил только одно слово, и все было готово.источник
findByFoo
для выявления несоответствий типов ранее.