上位の批判的レビュー
5つ星のうち3.0大局的な内容は有用。コーディング指南については一部賛同しがたい部分もあり
2022年5月7日に日本でレビュー済み
クラスベースのオブジェクト指向に基づく、設計のノウハウを解説した本。
自分としては、13章のモデリングの話が一番興味深かった。
単語としてはよく聞くものの実践が困難な「単一責任の原則」について、著者の考える実践の指針が説明されており参考になった。
一方で、それ以前のサンプルコードを元に良いコード/悪いコードを解説している部分は、読んでいていくつか違和感を抱く箇所があった。
---
最も気になったのは12.6.3の「エラーは戻り値で返さない、例外でスローすること」と題された節で、ミスリーディングな記述があると感じた。
本節では、位置を2次元座標を用いて表現するクラス Location の、位置を移動するメソッド shift(int shiftX, int shiftY) を例として扱っており、
「問題のあるエラー処理」の例として、移動後の位置(座標)が valid でなかった場合にはエラー値として Location(-1, -1) を返す、というものを紹介している。
そのうえで、これはある値に複数の意味を持たせる「ダブルミーニング」であってロジックの複雑さを招くため望ましくない、として、
「戻り値でエラーを返すのではなく、例外をスロー」すべきだと主張している。
しかしながら、「戻り値でエラーを返す」ために「ダブルミーニング」を用いる必要はない。
本書で用いられている Java であれば、shift を(Location 型を返すメソッドとして定義されているが)Optional<Location> 型を返す定義にして、
エラー値として Optional.empty() を返すようにすれば良い。
このようにすれば型レベルでエラー値と正常値の区別ができるので「ダブルミーニング」とは言い難いし、
これは何も Java 固有の機能ではない(例えば Rust であればこれに似た Option 型や、直和型を用いてより詳しくエラー情報を格納できる Result 型もある)。
さらに付言すると、Optional 登場以前の Java や、Ruby や Python のような動的型付け言語の場合でも、
Location(-1, -1) よりは null 値(nil / None)を返却するほうが一般的な手法と考えられる(それが良い手法かは措くとしても)。
以上のことから、本節の「戻り値でエラーを返す」ことのデメリットの説明は、適切でないと感じた。
もっとも、著者はこれ以前に5.5.1 節の「プリミティブ型執着」の中で、
「プログラミング言語が標準で用意している基本データ型」=「プリミティブ型」を濫用せず、1つ1つ丁寧にクラス化すべきである、と主張しているため、
もしかすると著者の考えとしては、Optional 型も(戻り値としては)使うべきでないのかもしれない。
(※Optional 型は Java の言語仕様的な意味ではプリミティブではないが、本書の中では String もプリミティブと呼ばれているため、本書の定義としてはプリミティブと呼べるかもしれない)
しかし、仮にそうだとすれば、なおさら Optional 型を使ったやり方に触れた上で、それよりも著者の推奨するやり方のほうが優れている、と示す論理展開がほしかった。
---
この箇所以外にもいくつか気になった部分はあったものの、
基本的には著者の一貫したスタンス(一つ一つの概念を丁寧にクラス化し、データとロジックを凝集させてゆく)が反映されていて、興味深く読める内容ではあった。
ただ、逆に言えば著者の思想が強く出ている(それが本書の魅力でもあるのだが)本であるからこそ、
前述したようなミスリーディングな議論を避けてほしかった。
上記のような理由から、本書の主張がどのくらい妥当なのか、は自分の中で判断保留の状態になっている
(13章以降の大局的な内容については妥当だと思うが、12章以前のコードの書き方指南については多少の疑義がある)。
それでも、間違いなく有用だと感じる部分もあったので、少しずつ徐々に本書の書き方を普段のコーディングに導入しながら(本書16章でもスモールステップでチームの設計力を高めていくことを推奨している)、
どの程度本書内のプラクティスが有効に働くのかを確かめてみたいと考えている。