私は、メソッドが戻り値を持っている(そして参照的に透過的である)か副作用を持っている必要があることを一度読んだことがありますが、両方はありません。この規則への言及はありませんが、もっと詳しく知りたいです。
このアドバイスの起源は何ですか?それはどの人またはコミュニティから生じましたか?
追加クレジット:このアドバイスに従うと主張される利点は何ですか?
グレッグ・ヤングによると、このアイデアはBertrand Meyer: Command-Query Separation に由来しています。
すべてのメソッドは、アクションを実行するコマンドか、呼び出し元にデータを返すクエリのいずれかである必要がありますが、両方ではないことを示しています。つまり、質問しても答えは変わりません。1 より正式には、メソッドは、それらが参照的に透過的であり、したがって副作用がない場合にのみ値を返す必要があります。
1: エッフェル:ソフトウェアエンジニアリングの言語 スライド43-48
ドメイン駆動設計では、これはGreg Youngによって命名されたコマンドクエリリード分離/分離(CQRS)に似ています。
Greg YoungはBertrandからCQSのアイデアを取り入れて、Martin Fowlerがこの CQRS記事 で言及したようにCQRSを命名しました
詳細は Martin Fowlerリンクの記事 を参照してください。
どこから来たのかはわかりませんが、良いアドバイスであり、理解するのもかなり簡単です。
きちんと設計されたプログラムは、さまざまな部分に分割され、さまざまな方法で結合および構成されます。特定の部分の動作を推論するのが難しいほど、プログラムが予測可能な方法で反応することを確認するのが難しくなります。
副作用を生成する部分を分離すると、残りの部分についての推論、テスト、およびデバッグが容易になります。副作用が発生する各パーツの副作用の数を減らすと、そのパーツを同じ方法で操作しやすくなります。
さらに分解すると、戻り値が影響します。副作用は効果です。関数が持つ入力と効果の数が多いほど、関数が実際に何をしているのかを推論することが難しくなるため、関数は1つの効果(可能な場合)のみを生成する必要があります。
追加クレジット:とは
最初に主張したこのアドバイスに従うメリットは?
戻り値を副作用から分離する利点の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
}