Существуют ли ситуации, когда побочный эффект операции "получить" или "вычислить" является допустимым?

Я только что закончил шестичасовой сеанс отладки для странного эффекта пользовательского интерфейса, когда обнаружил, что моя любимая реализация фреймворка интерфейсной функции под названием «getVisibleRegion» отключила некоторые функции пользовательского интерфейса (и, очевидно, забыл восстановить ее).

Я сообщил об ошибке в фреймворке, но это заставило меня задуматься о правильном проектировании: при каких условиях законно иметь какие-либо побочные эффекты для операции с именем, которое подразумевает простую операцию вычисления / получения?

Для тех, кто интересуется фактическими деталями: у меня был отчет об ошибке, из-за которой мой плагин продолжал нарушать сворачивание кода Eclipse, так что полоса сворачивания исчезла, и было невозможно «развернуть» или увидеть свернутый код. Я проследил это до вызова getVisibleRegion () в ITextViewer, тип которого представляет программу просмотра исходного кода. Теперь в документации ITextViewer указано, что «зрители, реализующие ITextViewerExtension5, могут быть вынуждены изменить отображаемые части входного документа, чтобы выполнить этот контракт». Фактическая реализация, однако, приняла это немного тоже и просто отключила проекцию (сворачивание) навсегда, чтобы никогда не вернуть ее.

В PHP
В PHP
В большой кодовой базе с множеством различных компонентов классы, функции и константы могут иметь одинаковые имена. Это может привести к путанице и...
Принцип подстановки Лискова
Принцип подстановки Лискова
Принцип подстановки Лискова (LSP) - это принцип объектно-ориентированного программирования, который гласит, что объекты суперкласса должны иметь...
4
0
161
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Я бы сказал «Нет».

obj.getBusyDoingStuff ()

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

Или же побочным эффектом get () может быть в первую очередь чтение значения из базы данных.

jalf 10.12.2008 05:44

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

Bill the Lizard 10.12.2008 05:53
Ответ принят как подходящий

Самая большая причина, о которой я могу думать, - это кеширование результатов.

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

Uri 10.12.2008 05:15

Я бы сказал, только если будет очень очевидно, что побочный эффект возникнет. Вот краткий пример:

  MakeMyLifeEasyObject mmleo = new MakeMyLifeEasyObject(x, y, z, default, 12, something);

  Object uniqueObjectOne = mmleo.getNewUniqueObject();
  Object uniqueObjectTwo = mmleo.getNewUniqueObject();

  System.out.println(uniqueObjectOne.getId() == uniqueObjectTwo.getId()); // Prints "false"

В моей теории MakeMyLifeEasyObject имеет некоторый внутренний счетчик (например, первичный ключ в таблице БД). Есть побочный эффект у get. Я также могу придумать что-то вроде этого:

  Object thing = list.getNextObjectAndRemoveFromList();

Это тоже имело бы смысл.

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

Первый вариант, вероятно, будет лучше createNewUniqueObject (), а второй - другое имя (в данном случае pop ()).

Когда это не какой-то наполовину надуманный пример, как я привел выше, я бы сказал, что ЕДИНСТВЕННЫЕ побочные эффекты, которые должны происходить, - это создание / обновление некоторого кеша, если значение требует много времени для создания или может использоваться совсем немного и требует быть ускоренным.

Примером этого может быть объект, содержащий набор строк. У вас есть метод getThingToPrint (), который должен объединить группу. Вы можете создать кеш, когда он будет вызван, и это будет побочным эффектом. Когда вы обновляете одну из строк, на которых основаны вещи, набор сделает кеш недействительным (или обновит его).

Что-то вроде того, что вы описали? Определенно звучит как ошибка. Я не могу придумать ситуацию, когда это было бы хорошей идеей. Если это предполагаемое поведение, а не ошибка, то его следует переименовать во что-нибудь другое (например, disableThingAndGetVisibleRegion ()).

Другие вопросы по теме