Что случилось с возвратом?

В компании я работаю над документом, описывающим хорошие практики, которые мы должны придерживаться на Java. Один из них - избегать методов, возвращающих this, например, например:

class Properties {

  public Properties add(String k, String v) {
   //store (k,v) somewhere
     return this;
  }

}

У меня был бы такой класс, чтобы я мог писать:

 properties.add("name", "john").add("role","swd"). ...

Я видел такую ​​идиому много раз, как в StringBuilder, и не нашел в ней ничего плохого.

Их аргументация такова:

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

Я не могу представить себе ситуацию, когда это может быть правдой, может ли кто-нибудь из вас дать мне пример?

РЕДАКТИРОВАТЬ В документе ничего не говорится о изменчивости, поэтому я не вижу разницы между цепочкой вызовов и выполнением:

properties.add("name", "john");
properties.add("role", "swd");

Я попытаюсь связаться с создателями, но я хотел сделать это с загруженным оружием, вот почему я разместил вопрос.

SOLVED. Мне нужно поговорить с одним из авторов, его первоначальное намерение состояло в том, чтобы, по-видимому, не выпускать объекты, которые еще не готовы, как в шаблоне Builder, и объяснили, что если переключатель контекста происходит между вызовами, объект может находиться в недопустимом состоянии. Я утверждал, что это не имеет никакого отношения к возврату this, поскольку вы могли бы совершить ту же ошибку, купив вызов методов один за другим и больше связавшись с синхронизацией процесса сборки должным образом. Он признал, что документ может быть более явным и вскоре пересмотрит его. Победа моя/наша!

Ответы

Ответ 1

Единственная серьезная основа для практики - избегать изменчивых объектов; критика, что она "запутывает" и ведет к "неудачным ожиданиям", довольно слаба. Нужно никогда использовать объект, не ознакомившись с его семантикой, а принудительные ограничения на API просто для того, чтобы обслуживать тех, кто отказывается от чтения Javadoc, не является хорошей практикой вообще -— особенно потому, что, как вы отмечаете, возвращение this для создания свободного API-интерфейса является одним из стандартных подходов в Java и действительно очень приятным.

Ответ 2

Я предполагаю, что они против изменчивого состояния (и часто это справедливо). Если вы не создаете плавные интерфейсы, возвращающие this, а вернете новый неизменяемый экземпляр объекта с измененным состоянием, вы можете избежать проблем с синхронизацией или не иметь "failed expectations about the states of target objects". Это может объяснить их требование.

Ответ 3

Я думаю, что иногда этот подход может быть действительно полезен, например, в шаблоне "builder".

Я могу сказать, что в моей организации такие вещи контролируются правилами сонара, и у нас нет такого правила.

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

Поэтому единственное, что я могу предложить здесь, - поговорить с людьми, которые написали этот документ:)

Надеюсь, что это поможет

Ответ 4

Я думаю, что вполне приемлемо использовать этот шаблон в некоторых ситуациях.

Например, как разработчик Swing, я часто использую GridBagLayout для своих сильных сторон и гибкости, но любой, кто когда-либо использовал его (вместе с ним причастный к преступности GridBagConstraints), знает, что он может быть довольно многословным и не очень читаемым.

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

Результирующий код составляет около 1/4 размера и гораздо читабельнее/поддерживается даже для случайного разработчика, который может быть не знаком с использованием GridBagConstaints.