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

При отладке кода клиента веб-сервиса сегодня (на 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.