Когда метод имеет слишком много параметров?

При отладке кода клиента веб-сервиса сегодня (в Java, с jax-ws) я столкнулся с методом веб-сервиса с умопомрачительным количеством 97 параметров!

Мне пришлось создать тестовый пример, который вызывает этот метод, и я заметил несколько вещей:

  • Кодовая помощь / наведение не очень хорошо масштабируется. Я использую Eclipse, а всплывающая подсказка над методом имеет ширину экрана и охватывает несколько строк.
  • Мне пришлось копировать значения параметров из предыдущего захвата xml, и было практически невозможно вспомнить «где я» – когда у меня был указатель, расположенный после запятой, и, прежде чем вводить какое-то значение, я часто ошибочно использовал тип данных – я набрал Integer вместо String и наоборот.
  • Даже после того, как я написал все параметры, у меня все еще были некоторые ошибки, и подпись не соответствовала. К сожалению, Eclipse отмечает всю строку в красном как ошибку, так что найти, где ошибка занимает еще больше времени 🙁

Итак, это заставило меня задуматься, как вы думаете, это максимальное разумное количество параметров для метода? И если вы можете изменить эту подпись веб-сервиса, как вы думаете, ее можно улучшить?

Нет четкого предела, но мне неудобно более 3-4 параметров. AFAIR Дядя Боб Мартин в « Чистом кодексе» рекомендует максимум 3.

Существует несколько рефакторингов для уменьшения количества параметров метода (подробнее см. « Эффективная работа с устаревшим кодом » Майкла Перса). Это приходит мне на ум:

  • инкапсулировать многие связанные параметры в один объект (например, вместо String surName, String firstName, String streetAddress, String phoneNumber передать объект Person содержащий эти поля)
  • передавать параметры в конструкторе или других вызовах метода до вызова этого метода

Когда вы должны спросить, это, вероятно, слишком много.

Как говорит Стив Макконнелл в Code Complete , золотое правило составляет 4 +/- 3 параметра. Для обычного человека трудно запомнить более 4 параметров, 5-7 следует использовать только в особых случаях, и вы никогда не должны использовать 8 или более.

Великий Будда! Девяносто семь????

Хорошая практика обычно советует о макс. от шести до восьми. Конечно, ymmv, и может быть веская причина, время от времени, девятый. Но 97 ?? !!

Несколько мыслей … это просто данные или решения принимаются на основе их ценностей?

Если многие / наиболее влияют на управление streamом, вы получаете почти незаметный (даже понятный или проверяемый) «дизайн» (для небольших значений «дизайн»).

Если это просто данные, они могут быть сгруппированы в структуры и указатели этих структур?

Есть ли у вас проектная документация? Мог бы это объяснить, что происходит.

О, и, «Опасность, Уилл Робинсон» – любой, кто открыто передаст 97 параметров, может также передать любое число – не так очевидно – как глобальные переменные.

Ps не знают, как Eclipse работает на Java, но с C / C ++, если вы поместите параметры на отдельные строки

 char DoEverything( int meaninglessParameterName1, char *meaninglessParameterName2, .... long double *meaninglessParameterName97) { return !NULL;} 

Eclipse фактически идентифицирует строку с плохим параметром

Хорошо, если вы сделаете объект JSON, вы можете обернуть все 97 (или больше) в этот объект и только отправить один объект.

Если его более 5-10 параметров, то создайте объект, который принимает параметры вместо этого, это может быть типизированный dataset, структура или что-то еще.

Вместо :

 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) 

По моему собственному опыту, я обнаружил, что сигнатуры методов начинают запутываться и запоминаться с более чем 5 или 6 параметрами. И как только вы получите 10 параметров, это просто смешно.

Эти параметры действительно необходимо объединить в объект (или небольшой набор объектов), в котором хранятся все данные. В службах, которые я использую, каждая операция обслуживания всегда принимает один объект запроса и возвращает один объект Response.

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

Для всего остального я нахожусь для 3 параметров и ocassionally идти до 5.

Ну, я бы предложил перегрузить метод, чтобы у вас были более простые реализации метода. Это может быть особенно полезно, если многие из параметров редко меняются и могут быть назначены по умолчанию. Однако, если память работает, я не думаю, что вы можете перегружать вызов веб-службы (вы должны использовать отдельное имя метода).

Другим возможным решением является инкапсуляция параметров в какой-то class метаданных, целью которого является сохранение параметров. Это упростило бы подпись метода. Однако в некоторых отношениях вы просто выгружаете проблему в class параметров. Но, если параметры можно отнести к темам, эта техника может быть использована путем использования нескольких classов метаданных, каждая из которых будет включена в качестве параметра для веб-службы. Это должно упростить вещи и помочь вам обмануть этого монстра.

Наконец, трудно сказать без каких-либо подробностей, но, безусловно, этот код является серьезным кандидатом на рефакторинг. У меня нет жесткого правила относительно количества параметров для метода, кроме того, чтобы принять общий принцип простоты и удобочитаемости.

  • Аргументы или параметры?
  • Последующее наблюдение: поиск точного «расстояния» между цветами
  • Каковы преимущества файлов с отображением памяти?
  • Давайте будем гением компьютера.