よし!じゃあやっぱりドキュメントもモデルもソースコードの劣化コピーだからいらないね
ってなるはずなのに、なんか違和感がある……。
だからソースコードになにが書かれているかを5W1Hで考えてみた。
How どうやって
レジスタ1とレジスタ2の加算結果を、メモリのxxx番地に格納して、
メモリxxx番地の値と比較して xxx ならプログラムカウンタを
xxx に飛ばして……。
How はすべてソースコードにすべてもれなく記載されている。だから How をドキュメントに記載する必要はない。
ドキュメントには本質的な部分だけを記述するよう、オッカムの剃刀でどんどん切り落としてほしい。
ただ、トレーサビリティのために必要な部分まで削ぎ落とし過ぎないように。
What なにを / Why なぜ
レジスタ1とレジスタ2の加算結果を、メモリのxxx番地に格納して、
メモリxxx番地の値と比較して xxx ならプログラムカウンタを
xxx に飛ばして……。
って 結局なにがしたいの?
ソースコードはマシンが理解できるように詳細に書かれているが詳細すぎてそれが なにをするもの なのか 何のためのもの なのかが読み取れなくなっていることが多い。
トップダウンで記述するならCODE COMPLETE 9章PseudocodeProgramingProsess。なにをやりたいかをコメント文、自然言語でソースコードっぽく記載する方法。
ボトムアップで記述するなら USDM スペックアウト。そのソースコードはなにをするものなのか、なにを満たすのか、なぜそのような要求があり、そのような仕様になっているかを記載する。
関数や変数の名前付けにこだわることでソースコードだけでも表現することは可能だ。
限界があるとしたらコメント文でもいい。
またコミットコメントにはHowではなくWhat/Whyを残すようにしよう。
Who 誰が どのモジュールが / Where どこが どのぐらいの範囲で
ここから先は図や表などを用いないと表現しづらいかもしれないなー。
先のUSDMでも紹介されているトレーサビリティマトリクスや、クラス図、アクティビティ図でどのモジュールがどんな責務を担っているかが見渡せるだろう。そしてある仕様を変更した場合にどこのモジュールをどのぐらいの範囲に渡って変更しなければならないかが見えることで、より良い設計、テスト・実装が進められるだろう。
細部の一つ一つがすべて記載されたソースコードを見るよりも、スケッチとして全体像を写し取った UML のありがたみを感じられるはず。
マーチン・ファウラーさんもスケッチとしてのUMLについて以下のように述べている。
私はUMLをスケッチとして使用します。UMLによるスケッチは、
フォワードエンジニアリングとリバースエンジニアリングのどちらにも使え、
概念的観念とソフトウェア的観点のどちらにとっても便利だと思います。
When いつ、どのような順序で、どのぐらいの期間
ソースコードをエントリーポイントから読み解いて行けば、処理順序は確かに読み解ける。
でもコールバック関数が呼び出されるタイミングや、メモリなどのリソースの生存期間、競合期間は、ソースコードからは読み取りづらい。
アクティビティ図、シーケンス図を使うと、これらを容易に読み解くことができる。
ただ初学者がよく書きたがるシーケンス図はソースコードを見ればわかることしか記載されていないものがある。そんなシーケンス図が嫌いだ。
シーケンス図は、モジュール遷移のトリガーとなるメソッドを際立たせたり、クリティカルなタイミングのリソース生存期間、競合期間などを記載できるのが良いところで、逐次処理していくだけのものを記載するだけであれば、ソースコードを見るほうが有益なはずだ。
トップダウン/ボトムアップ 合理主義、経験主義 選択的無知
実践からの学びはボトムアップ、帰納的だが、それを説明するにはトップダウンで演繹的に説明するほうが伝わりやすい。
コーディング、テストを通じて得た学びをモデル図にフィードバックしよう。モデル図を見ながらよりシンプルなシステム構成を探ろう。
ソフトウェア開発は選択的無知で日々成長している。コードの詳細は知らなくても、やりたいことができる。そんなソフトウェアシステムを構築していくには、よく読んで、よく書いて、よく推敲して、システムとスキルを磨き上げよう。
ドキュメントやモデルには苦しんだ経験を明日の誰かのために書く
最後に
書きながら、うろ覚えの書籍を読み返したりしているうちに、なんかツッコミどころが満載な気がして自信がなくなってくるけど、いったん公開してみる。🎉
がっさり改定しないとだめかもだけど。🙂