Происхождение «метод должен возвращать значение или иметь побочные эффекты, но не оба»

12

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

Каково происхождение этого совета? Из какого человека или сообщества это возникло?

Дополнительный кредит: Какая заявленная выгода от следования этому совету?

Уэйн Конрад
источник
1
@gnat Да, это прежде всего история. Я боялся, что дополнительная часть кредита была слишком субъективна, чтобы стоять сама по себе, и что история имела больше шансов избежать закрытия. Я добавлю тег.
Уэйн Конрад
некоторые ответы, которые накапливались, заставили меня задуматься, спрашиваете ли вы о пользе, на которую претендовал автор данного совета, или о списке всех льгот, на которые можно претендовать вообще?
комнат
@gnat Я спрашиваю о пользе, заявленной автором (опять же, опасаясь закрытия), но я точно не возражаю против навязчивых причин - они отвечают на вопрос, который я на самом деле хотел задать. Если бы я убрал «заявленное» из моего вопроса, сделав кучу ответов по теме, разве это бы толкнуло вопрос слишком далеко в субъективном?
Уэйн Конрад
«Причины кучи», скорее всего, заставят закрыть вопрос как слишком широкий . Если вы предпочитаете, чтобы оно «оставалось на открытой стороне», я думаю, что было бы безопаснее сузить его до выгоды, на которую претендовал автор
комнат
Одним из преимуществ является то, что если вам платят за объем кода, это приводит к дополнительным. "doSomething; GetResultOfSomething; HandleErrorsFromSomething;"
ღ uі

Ответы:

13

По словам Грега Янга, эта идея возникла у Бертрана Мейера : разделение команд и запросов .

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

1: Eiffel: язык для разработки программного обеспечения, слайд 43-48

В управляемом доменом дизайне это похоже на разделение / разделение команд-запросов-чтений (CQRS), как его назвал Грег Янг.

Грег Янг взял идею CQS от Bertrand, чтобы назвать CQRS, как упомянуто Мартином Фаулером в этой статье CQRS

Преимущества

  • Часть Read (Query) может быть изменена или изменена иначе, чем часть Write (команда). Разделение этих двух препятствовало бы тому, чтобы оба мешали друг другу, когда оптимизация / производительность являются ключевыми.

Прочитайте статью в ссылке Мартина Фаулера для получения дополнительной информации.

Tunmise Fasipe
источник
1
Естественно, что во многих ситуациях получение полезного результата и внесение некоторых изменений в одно и то же время обходится не дороже, чем выполнение более сложного из двух по отдельности.
Дедупликатор
1
@Deduplicator Примером клише является InterlockedCompareExchange?
ღ uі
1
Этот совет, очевидно, неприменим, когда возвращаемая информация является некоторой информацией о том, что было сделано в команде, однако - метод удаления строк из набора данных может в значительной степени изменить состояние набора данных, удаляя указанные строки в соответствии с заданным критерием, и затем возвращает количество удаленных строк или даже список с указанными строками.
Т. Сар
4

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

Любая разумно разработанная программа будет разбита на различные части, объединены и составлены различными способами. Чем сложнее рассуждать о том, что делает какая-то конкретная часть, тем сложнее будет убедиться, что ваша программа будет реагировать предсказуемым образом.

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

Если вы разложите его еще дальше, возвращаемое значение будет эффектом. Побочные эффекты - это эффект. Функция должна производить только 1 эффект (если это возможно), потому что чем больше входов и эффектов имеет функция, тем сложнее рассуждать о том, что она на самом деле делает.

Morgen
источник
это даже не попытка ответить на заданный вопрос, см. Как ответить
комнат
@gnat Мой вопрос состоял из двух частей: основного вопроса («кто») и дополнительного кредита («почему»). Разве это не касается дополнительной части кредита?
Уэйн Конрад
согласно моему прочтению (« заявленная выгода»), почему-часть должна быть предложена автором цитаты. Вопрос, кажется, не спрашивает список всех возможных преимуществ
комнат
2
@gnat Я понял вопрос как попытку понять этот совет, как причину его возникновения, так и контекст, в котором он был дан. Я не верю, что было бы неуместно решать только часть вопроса.
Морген
1

Дополнительный кредит: Какова изначально заявленная выгода от следования этому совету?

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

bool FooWithSideEffect() {
    // do query
    // do side effect
    return resultOfQuery;
}

bool BarWithSideEffect() {
    // do query
    // do side effect
    return resultOfQuery;
}

void BadShortCircuitEvaluation()
{
    // the programmer's intent is to have side effects of both functions
    if (FooWithSideEffect() && BarWithSideEffect() ) {
        // do something
    }

    // in case FooWithSideEffect() returns true, 
    // then BarWithSideEffect() is not called at all
    // because of short-circuit evaluation
}
Ник Алексеев
источник
это преимущество, заявленное автором совета ?
комнат
Боюсь, я перепутал историческое и практическое.
Ник Алексеев
1
комментарий и код не совпадают, BarWithSideEffects не вызывается, если FooWithSideEffects возвращает false
jk.