Как мне разработать сигнатуру метода для следующего сценария - PullRequest
2 голосов
/ 28 июня 2011

Если у вас есть метод, в котором входной параметр может быть выходным.

Допустим, у нас есть метод save, который генерирует автоматически сгенерированный идентификатор, который клиент может быть заинтересован использовать после вызова save ().

Person

  • id (автоматически сгенерированный)
  • name
  • ... (другие поля)

Если вы создадите сигнатуру метода следующим образом:

1.

public void save(Person person);

Клиентский звонок:

personService.save(person);
System.out.println(person.getId());

2.

public Person save(Person person);

Клиентский звонок:

person = personService.save(person);
System.out.println(person.getId());

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

В настоящее время я знаю, что метод не будет удаленным вызовом, поэтому я мог разработать его с использованием первой сигнатуры.Но что, если в будущем это изменится, и его нужно будет называть удаленным вызовом.

Поэтому мой вопрос: должен ли я разработать свой API, думая, что в будущем этот API может быть вызван как удаленный вызов, ине используете параметр объекта как способ вернуть значение клиенту (2), или я должен разработать свой API в соответствии с моей реальной ситуацией, когда служба не является удаленной (1)?

Спасибо

Ответы [ 3 ]

1 голос
/ 28 июня 2011

Это нормально, чтобы сделать оба; save() возвращает новый идентификатор , а имеют метод getId(). Возвращение значения из «установщика» (метода, который изменяет состояние) имеет множество прецедентов - API коллекций Java делает это все время, например, Map.remove(Object) возвращает boolean.

Свободный интерфейс

Есть еще один шаблон, который вы можете рассмотреть, шаблон Fluent Interface . Используя свободный API, вы возвращаете объект (т. Е. this) из каждого метода, который в противном случае возвращал бы void. Это позволяет вызывающей стороне «связывать» вызовы методов. С быстрым интерфейсом ваш код будет выглядеть так:

public Person save() {
    // do your save stuff
    return this;
}

Если вы хотите, чтобы идентификатор был сохранен, введите код:

save().getId();

Simple! Этот шаблон также использовался во многих существующих java-кодах, особенно в спящем режиме, как в этом примере свободного кода java

Я бы порекомендовал использовать беглый, если не более, чтобы получить практику, используя его

1 голос
/ 28 июня 2011

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

При этом, как правило, мне неудобны методы, которые изменяют свои параметры, если только это не является их единственной целью, и они названы и задокументированы для указания этого. С точки зрения «что делает метод, и какую новую информацию я получаю от него», я, вероятно, выбрал бы такую ​​подпись:

public ID save(Person);
0 голосов
/ 28 июня 2011

Я бы рекомендовал использовать первый подход, поскольку объекты редко используются изолированно.На объект Person обычно ссылаются другие сущности, такие как Employee.Если вы создаете новый экземпляр, вы лишаете законной силы весь граф объектов и, поверьте мне, вы не хотите возиться с глубоким копированием.

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

@ CPerkins - Объекты передаются по «справочному значению», чтобы быть абсолютно корректными;)

...