delhi09の勉強日記

技術トピック専用のブログです。自分用のメモ書きの投稿が多いです。あくまで「勉強日記」なので記事の内容は鵜呑みにしないでください。

『リファクタリング』読書メモ (問い合わせと更新の分離 [Separate Query from Modifier])

概要

マーティン・ファウラーの『リファクタリング』が勉強になることがたくさん書いてある素晴らしい本だったので、読んだ感想や考えたことをセクション毎などの適当な粒度でメモしていきたいと思う。

www.ohmsha.co.jp

今回は「第11章 APIリファクタリング」の「問い合わせと更新の分離(p.314)」について書く。

「問い合わせと更新の分離」の概要

関数(API)を実装する際に、副作用がある関数とない関数は明確に分離するべきという主張が書かれている。
また。 そうすることで何が嬉しいのかというメリットも記載されている。

感想

なるほどと思った箇所としては、「副作用がある関数とない関数の分離」に関して、

値を返す関数は、観察可能な副作用を持ってはならないというルールを取り入れるべき

と本セクションでファウラーは主張していることである。
※ 「観察可能な」という言葉には重要な意味が込められているのだが、それはここでは話題にしない。

上記の主張は、裏を返すと「副作用のある関数では戻り値を返してはいけない(=void型にしなければならない)」と言っていることになり、単に「副作用がある関数とない関数は分けるべき」というやや漠然とした主張よりも、より厳密で踏み込んだ定義だなと思った。

というのは、単に「副作用がある関数とない関数は分けるべき」という主張からは、「副作用のある関数では戻り値を返してはいけない」ところまでは、少なくとも言葉上からは、読み取れないからである。(そういう思いも込められているのかもしれないが)

たしかに、単に「副作用がある関数とない関数は分離しましょう」だと漠然としていて、人によって解釈が違ったり、「この程度は許容範囲」の考え方が違ったりしそうなので、「副作用のある関数では戻り値を返してはいけない」という言葉にした方が、やるべきこと明確になるし自分でコーディングする際の指針としても適用しやすくなるので良さそうだなと思った。
※ ただ、少し疑問に思ったことはあって、それは「疑問」の項に書いた。

また、完全に別の感想として、最近、アーキテクチャ設計の議論ではCQRS(コマンドクエリ責務分離)の話題をよく耳にするが、関数を1つ作成するというもっと小さいレベルでも、こういうことは原則として意識するべきなんだろうなと思った。

疑問

「副作用のある関数では戻り値を返してはいけない」という指針は基本的には良いなと思ったものの、例えば「RDBに新しくデータを作成(INSERT)する場合」はどうなんだろう?と思った。

というのは、この場合、戻り値で自動採番されたIDを取得しないと、アプリケーション側で新規作成されたデータを追跡できなくなってしまうからである。

もちろん、RDBのAUTOINCREMENT機能を使わずに主キーの値をアプリケーション側で生成したり、自動採番の仕組みを採番テーブルを作って自前で実装したりすれば、戻り値で主キーを返す必要はなくなるかもしれないが、そこまでこの原則を徹底することにメリットはあるんだろうか?というのは少し疑問に思った。

ファウラー自身も

私は「値を返す関数は、観察可能な副作用を持ってはならないという」という原則を絶対的なルールにすることについて(何についてもそうですが)100%賛成ではありませんが、多くの場合はこのルールに従うようにしています。

と書いていたので、「100%賛成ではない」の部分はもしかしたらこの辺りなのかな?と思った。