Когда метод имеет слишком много параметров?
При отладке кода клиента веб-сервиса сегодня (на Java, с jax-ws) я столкнулся с методом веб-сервиса с продуманным количеством 97 параметров!
Мне пришлось создать тестовый пример, который вызывает этот метод, и я заметил несколько вещей:
- Кодовая помощь/наведение не масштабируется. Я использую Eclipse, и всплывающая подсказка над методом имеет ширину экрана и охватывает несколько строк.
- Мне пришлось копировать значения параметров из предыдущего захвата xml, и было практически невозможно запомнить "где я" - когда у меня был курсор, расположенный после запятой, и, прежде чем вводить какое-то значение, я часто получал тип данных неправильно - Я набрал Integer вместо String и наоборот.
- Даже после того, как я написал все параметры, у меня все еще были некоторые ошибки, и подпись не соответствовала. К сожалению, Eclipse отмечает всю строку красного цвета как имеющую ошибку, поэтому найти, где ошибка занимает еще больше времени: (
Итак, это заставило меня задуматься, как вы думаете, это максимальное разумное количество параметров для метода? И если вы можете изменить эту подпись веб-сервиса, как вы думаете, ее можно улучшить?
Ответы
Ответ 1
Нет четкого предела, но мне неудобно более 3-4 параметров. AFAIR Дядя Боб Мартин в Чистый код рекомендует максимум 3.
Существует несколько рефакторингов для уменьшения количества параметров метода (подробнее см. Эффективно работая с устаревшим кодом, Майклом Перусом). Это приходит мне на ум:
- инкапсулировать многие связанные параметры в один объект (например, вместо
String surName, String firstName, String streetAddress, String phoneNumber
передать объект Person
, содержащий их как поля)
- передать параметры в конструкторе или других вызовах метода до вызова этого метода
Ответ 2
Когда вам нужно спросить, это, вероятно, слишком много.
Ответ 3
Как говорит Стив Макконнелл в Code Complete, золотое правило - 4 +/- 3 параметра. Для обычного человека трудно запомнить более 4 параметров, 5-7 следует использовать только в особых случаях, и вы никогда не должны использовать 8 или более.
Ответ 4
Великий Будда!! Девяносто семь????
Хорошая практика обычно советует о макс. от шести до восьми. Конечно, ymmv, и может быть веская причина, время от времени, девятый. Но 97??!!
Несколько мыслей... это просто данные, или решения принимаются на основе их ценностей?
Если многие/наиболее влияют на управление потоком, вы получаете почти незаметный (даже понятный или проверяемый) "дизайн" (для небольших значений "дизайн" ).
Если это просто данные, они могут быть сгруппированы в структуры и указатели этих структур?
Есть ли у вас проектная документация? Может это объяснить, что происходит.
О, и "Опасность, Уилл Робинсон" - любой, кто открыто передаст 97 параметров, может также передать любое число - не так очевидно - как глобальные переменные.
Ps не знают, как работает Eclipse на Java, но с C/С++, если вы поместите параметры на отдельные строки
char DoEverything(
int meaninglessParameterName1,
char *meaninglessParameterName2,
....
long double *meaninglessParameterName97)
{ return !NULL;}
Eclipse фактически идентифицирует строку с плохим параметром
Ответ 5
Хорошо, если вы сделаете его объектом JSON, вы можете обернуть все 97 (или больше) в этот объект и отправить только один объект.
Ответ 6
Если его более 5-10 параметров, тогда создайте объект, который принимает параметры вместо этого, это может быть типизированный набор данных, структура или что-то еще.
Вместо:
Mywebservice.CreateUser(Firstname, LastName, Age,Sex, Haircolor,AmountOfFingers,AmountOfTeeht,Childrens,,,,,,,,,,,,,and so on)
делать:
Dim MyUser as new UserObject
MyUser.Firstname="Stefan"
...and so on...
MyWebservice.CreateUser(UserObject)
Ответ 7
По моему собственному опыту, я обнаружил, что сигнатуры методов начинают запутываться и запоминаться с более чем 5 или 6 параметрами. И как только вы получите 10 параметров, это просто смешно.
Эти параметры действительно необходимо объединить в объект (или небольшой набор объектов), в котором хранятся все данные. В службах, которые я использую, каждая операция обслуживания всегда принимает один объект запроса и возвращает один объект Response.
Ответ 8
Ну, я бы предложил перегрузить метод, чтобы у вас были более простые реализации метода. Это может быть особенно полезно, если многие из параметров редко меняются и могут быть назначены по умолчанию. Однако, если память работает, я не думаю, что вы можете перегружать вызов веб-службы (вы должны использовать отдельное имя метода).
Другим возможным решением является инкапсуляция параметров в какой-то класс метаданных, целью которого является сохранение параметров. Это упростило бы подпись метода. Однако в некоторых отношениях вы просто выгружаете проблему в класс параметров. Но, если параметры можно отнести к темам, эта техника может быть использована путем использования нескольких классов метаданных, каждая из которых будет включена в качестве параметра для веб-службы. Это должно упростить вещи и помочь вам обмануть этого монстра.
Наконец, трудно сказать без каких-либо подробностей, но, безусловно, этот код является серьезным кандидатом на рефакторинг. У меня нет жесткого и быстрого правила о числе параметров для метода, кроме того, чтобы принять общий принцип простоты и удобочитаемости.
Ответ 9
Что касается веб-сервисов, я предпочитаю обрабатывать параметры как один объект. В то время как контракт с вашими данными может измениться, ваш серийный контракт не будет. Это делает ваши услуги более перспективными.
Для всего остального я для 3 параметров и ocassionally иду выше 5.