Подтвердить что ты не робот

Лучше ли передавать ссылку на объект или передавать отдельные атрибуты в объекте в Java?

Я имею дело с устаревшим кодом, и я постоянно вижу вызовы методов с несколькими атрибутами от одного и того же объекта, передаваемого в метод:

update(user.getID(), user.getLanguage() etc...)

Есть ли явное преимущество или недостаток в том, чтобы делать это таким образом, или я просто должен был бы также пройти в пользовательском объекте (в данном случае) и иметь дело с атрибутами в методе, который называется?

Follow Up:

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

4b9b3361

Ответ 1

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

Pro несколько значений, ссылка на объект:

  • вы не привязаны к определенному классу, вы можете передавать значения из других источников
  • метод не может (неожиданно) изменить состояние объекта (для этого С++ может использовать для этого константу)

Pro, передающий один пользовательский объект:

  • вы привязаны к пользовательским объектам, что затрудняет случайное использование несвязанных/недопустимых значений
  • очевидно, что метод ожидает данные пользовательского объекта
  • изменение (например, переименование) геттер требует изменений во всех вызовах метода, а не только в его реализации
  • похоже, если новое свойство добавлено и должно быть передано
  • метод может изменять состояние объекта

Как вы видите, свойство может считаться преимуществом или недостатком в зависимости от ваших потребностей.

Ответ 2

На самом деле было бы намного лучше передать ссылку на объект по двум причинам:

  • он избегает повторения всех геттеров во всех местах, вызываемых методом (принцип DRY)
  • это приводит к более коротким сигнатурам метода. В методах почти никогда не должно быть более трех параметров, потому что слишком легко путаться с порядком и сложно рефакторировать.

Чтобы избежать чрезмерно длинных списков параметров, рекомендуемый рефакторинг - это создание объекта, который содержит все данные - вам не повезло, что у вас уже есть такой объект?

Ответ 3

Это зависит от того, будет ли вы принимать зависимость от класса объекта от вызывающего метода.

При использовании этого

update(user)

Класс, в котором объявлено обновление, должен знать класс пользователя.

Если вы используете этот

update(user.getID(), user.getLanguage() etc...)

и члены являются примитивами или принадлежат стандартной библиотеке Java, чем нет никакой дополнительной зависимости в update() для класса пользователя...

Ответ 4

  • Это выглядит странно.
  • Это означает, что подпись метода выглядит как update(String, String, String...), которая вводит риск передачи аргументов в неправильном порядке
  • Если вам нужно принять новый атрибут во внимание в вашем методе обновления на определенном этапе, вам не нужно будет менять подпись метода, а только его реализацию.
  • Я не знаю, что делает update, но имеет смысл сделать его частью класса пользователя: user.update(additionalInformation).

Ответ 5

По моему опыту я думал, что это зависит от того, что должен делать метод, если он строго связан с объектом, который содержит все параметры, лучше передать объект, например, в объект DAO, который выполняет обновление или сохранить лучше передать объект Domain, иначе, если метод более общий, и есть вероятность, что все параметры не принадлежат одному и тому же объекту, лучше передать параметры методу.

Ответ 6

Немного сложно сказать, что это ваш метод обновления из вашего фрагмента кода. Но если вы пройдете в пользовательском объекте, вы уложите объект пользователя в этот метод. Если вы просто передаете строки, int и т.д., Вы можете использовать этот метод с источниками, отличными от пользователя. Мой совет заключается в том, что вы не должны заставлять метод быть более конкретным, чем это должно быть.

Ответ 7

Учитывая, что вы имеете дело с устаревшим кодом, вы должны быть уверены, что изменение метода

Подпись

не нарушает код, который может быть вызван. Если у вас есть полный контроль над базой кода, которая вызовет эти методы, то да, вы можете упростить код, просто передав объект user.

Вы также должны рассмотреть вопрос о том, подвергает ли пользователь объекту "тяжелого веса", который загружает дополнительные данные, которые могут быть расточительными для создания, каждый раз, когда вы вызываете эти методы. Это будет одной из причин, по которой вы не можете передать объект user в качестве параметра. Такая же причина применима к ленивым объектам.

Другой возможной причиной не пропускания всего объекта через может быть то, что вы не хотите, чтобы он был обновлен методом и "по какой-то причине" нельзя сделать неизменным. Методы геттера для пользовательских объектов могут быть сделаны для возврата "безопасных защитных копий" значений. См. Joshua Bloch эффективный java для этого типа практики кодирования, особенно полезный в приложениях с несколькими потоками.

Ответ 8

Нет преимущества в передаче свойств одного объекта в качестве отдельных аргументов методу. Недостатком этого является то, что код становится трудно читать и поддерживать. Чем меньше аргументов, тем лучше. Если вы можете объединить аргументы в одном объекте, просто сделайте это.

Существует метод рефакторинга, если вы хотите реорганизовать это, называемое Сохранить весь объект. Вы также можете найти мой ответ по тому же вопросу, который будет полезен.

Ответ 9

Это своего рода запах кода, который заставит меня рассмотреть возможность переноса метода update() в класс пользователя. Одна из великих принципов объектно-ориентированного дизайна encapsulation - объединить ваши данные и операции над этими данными вместе.

Затем у вас есть Сообщить, не спрашивать. Лучше сказать объекту что-то сделать, чем запросить у него информацию.

Процедурный код получает информацию, затем принимает решения. Объектно-ориентированный код сообщает объектам что-то делать.

Конечно, у меня нет достаточно подробностей, чтобы сказать, что вы обязательно должны сделать что-то подобное, но это что-то рассмотреть.