これまでの第十章
副作用のない関数
2種類の操作
- クエリ・・・システムから情報を取得する操作
- コマンド・・・システムに何かしらの変更を与える操作
上記の2種類の操作がある中で、問題になるのは「コマンド」です。
副作用
たとえば、あるコマンドを実行し、システムの状態を変更した後に、同じコマンドを同じように実行したらエラーになってしまったり、別の状態になってしまうとかありますよね。
こういう状態を副作用と言ったりします。
これがまた、コマンドから複数のメソッドを呼び出していたりすると、コマンドを実行したところ、どういう結果になるのかがわからなくなります。
副作用のない関数
ただ、コマンドを利用しないわけにはいきませんので、副作用の起こさないように実装することが大事になってきます。
同じコマンドを同じように実行したら同じ値が返って来る操作を関数といいますね。
関数を利用すれば、テストもしやすくなりますし、操作の中身もわかりやすくなるはずです。
どう実装するか
①. コマンドとクエリを分ける。同じ操作で2つのことをしない
コマンドとクエリを一緒におこなわないこと。クエリでドメインの中身を変更しないこと。コマンドでクエリの結果を返さないことです。
②. オブジェクトを変更するのではなく、処理の結果を反映した新しい値オブジェクトを返す
値オブジェクトのところでも読みましたが、オブジェクトを不変にすること。
"ロジックや演算"と"状態の変更"の操作を分離し、"ロジックや演算"を値オブジェクトへ移動する。"状態の変更"は新しい値オブジェクトを返す。
こうすれば、副作用がない(何度実行しても同じ値が返る)関数を実装できます。
実際、よく実施しているリファクタリングではありますが、こうして整理すると納得感が増しますね。
問い合わせと更新の分離[リファクタリング]
MartinFowlerも同じことを言っていますね。リファクタリングのパターンにも含まれています。