「A Philosophy of Software Design」を読んだ
A Philosophy of Software Design, 2nd Edition (English Edition) / John Ousterhout を読んだので感想を書く。
きっかけ
e34.fmで紹介されており、Software Designというキーワードに興味が湧き、何か得るものがあるかもしれないと思い読んだ。
感想
英語の書籍ではあるものの、平易な文章がほとんどだった。主題としては「ソフトウェアの複雑さ(complexity)に立ち向かっていくためのSoftware Designとは」というものだった。
e34.fmでも言及されていたDeep Module, Shallow Moduleの話をはじめ、コード中のコメントに対する考え方など、新しい発見や改めて考えさせられるものも多く、面白かった。
complexityとは?
システムのcomplexity C を以下のように定義しているところが興味深い。
\[ C = _{p} c_p t_p \]
ここで p はシステムのある部分、 cp がその部分のcomplexity、 tp が開発者がその部分に費している時間の割合だ。 つまり、読んだり改修したりするのに時間がかかる部分ほど複雑、ということのようだ。 単純に時間でいいのか?という疑問も湧いたが、代案と呼べるほどのものは思いつかなかった。
complexityの原因とは?
以上のようにcomplexityを定義したあと、 “dependencies”(依存関係) と “obscurity”(不明瞭さ) の2点がcomplexityの原因となると述べられていた。
対策とは?
これらの原因に対応するため、いくつかのdesignのポイントや心得などが述べられていく。
個人的に興味深かったものをいくつかピックアップしていく。
まず大事なのはtacticalではなくstrategicにプログラミングを行うことだと述べられており、抽象的な構造を考えてデザインしていくことの大切さが説かれていた。もちろん目の前のタスクをこなすのに、場当たり的なコードを書いたほうがその場の改修コストは小さくすむこともある。しかし、全体の10-20%時間をstrategicなdesignにするための投資時間に充てるほうがいいのではないか、という提案がされていた。これについては科学的な根拠はないとのことだったが、数ヶ月後にはそのメリットを享受できるだろう、とされていた。このあたりはt_wadaさんの「質とスピード」の話1でも似たような話がでてきたかと思う。
また、コードがstrategicになるように2回設計(Design It Twice)するように薦められている。凡人である自分も、一度手を動かしてみてやっと見えてくる部分があるため、2回設計と聞くと手間はかかりそうだが、長期的な視点に立ってやってみてもよいかもしれないと思えた。
Deep Module, Shallow Module
Deep Module, Shallow Moduleの話の説明はいろいろなところで言及されているので、他のブログ2に譲るとして、作者が classitis と揶揄している症状が面白かったのでそこに言及しておく。-itis というsuffixは「炎症」という意味があり、adenitis(リンパ節炎)、tonsillitis(扁桃炎)などで使われる。 classitis は和訳すると”クラス病”、“クラス炎”などになるだろうか。shallowなクラスが大量にできてしまう状態を作者はこう言っている。自分は普段Ruby on Railsアプリケーションを書くことが多いので、Rubocopなどのlinterにクラスの行数が多すぎることの警告を受けることがある。もちろん分割することにもある程度利点はあると思うが(もちろん、利点がなければlinterに入らないだろう。)、一方で意味のない分割になりがちだな、と思うことも多々ある。classitisとはそのようにクラスが長くなるから、という理由だけで意味のない分割をする衝動に駆られて続々とクラスを作ってしまうという状態なのだろう。
Information Leakage
Deep Moduleを作る上で注意することとして、Information Leakageを避けよ、という話もあった。Information Leakageとは複数の場所に同じ情報が書かれていることを指す。
ざっくり言うと「高凝集・疎結合」の反対、と言い換えることもできるだろう。また、DDDにおける「ドメインモデル貧血症」もこのInformation Leakageと似た話だと認識している。
また、よく使われる「decoratorパターン」についても著者は導入前によく検討すべきだと書いていた。Ruby on Railsアプリケーションを書いているとview用のロジックをmodelに書くのではなく、decoratorなどにまとめるべき、という話がよくあるが、その切り分けは自明ではないことも多い。そのため、あとからview以外の他の箇所でも使いたくなることがある。自分も最近はむやみに切り分けず、ある程度fat modelを許容してmodelにまとめるほうが結局いいのではないか、と思っている。もちろんこの辺りはアプリケーションの規模やコンテキストに依るところも大きいだろう。
コメントについて
コード中のコメントは忌避されることも多い。「コードを読めばいいからコメントは不要」という話を聞くこともある(し、自分も言ったことがあると思う)。この本ではコメントは基本的に書くべきもの、と位置づけていて、「コードを読めばいいからコメントは不要」などの言説についても反論を書いていて興味深かった。 もちろん無闇にコメントを書けばいいわけではなく、コードと重複するようなコメントはやはり不要で、もっと抽象的な部分、例えばその実装に至った意図や背景の説明に使うように書いてある。
まとめ
DRY原則への配慮やlinterからの指摘により「コードの見た目を整える」意味での形だけのコード整理をしてしまっている、というのをときどき見かける。とりあえず目の前のタスクを倒すコードを書き出す前に一回立ち止まって、strategicなdesignのコードになっているか?deepなクラス、モジュールを作れているか?を自問してみてるといいかもしれない。全体像の把握が難しければ、ある程度書いたあとに、Design It Twiceの精神でstrategicに最初からコードを書き直すとどうなるか?を考えてみてもいいかもしれない。