ソフトウェア設計で大切なこと(1/2)
明けましておめでとうございます。
去年は少し、アジャイル・アジャイル言い過ぎた気がしており、今年はもう少し大切なことの範囲をエンジニアリングに回帰して、再度言おうと思っています。
オブジェクト指向やテスト技法をはじめとするソフトウェア工学の知識とスキルは、ソフトウェア開発に携わる人には絶対必要なもので、その上で、プロジェクトマネジメント手法としてのアジャイルがある。
ということは、もういちどちゃんと言っておこう。そう思った動機は、James Shore の「Art of Agile Development」を訳したこと。そして、それはXPの本だったこと。ここ3年くらいXPという言葉はAgile界では下火になっていて、AgileといえばScrumという風潮だったのが、「エンジニアリングの無いScrumは所詮うまく行かない」、というJames Shoreの当然な一撃があった。InfoQの日本語記事がわかりやすい。「InfoQ: Agileの衰退と凋落」
もう1つ、ぼくはこの業界に今年で20年目となる。その間変わったものと、変わらなかったものがあり、ソフトウェアの設計に関する原則は、ほとんど変わらずにそのままある、ということに気づいた。構造化からオブジェクト指向になり、さらに、言語が動的になってても、ずっと変わっていないこと。それは、
よいソフトウェア設計とは、
- 凝集度が高い(high cohesion)
- 結合度が低い(low coupling)
- 重複がない(ZERO duplication)
- テスト容易性が高い(testability)
- 可読性が高い(readability)
ことだということ。
1-2 は、構造化設計のモジュール分割の基本である。これはオブジェクト指向設計のクラス分割でもそのまま踏襲されている。
3は、古くは「関数」、さらに古くは「マクロ」(アセンブラなど)という形でよく行われる処理を一まとめにしたりしてきた(今では当たり前)。これが、XP(Once and Only Once)やPragProg(DRY: Don't repeat Yourself) で特にここ10年間焦点があたってMUST項目になった。これは、Refactoring技術の進化やアジャイルで進化的設計が必要とされたことが大きい。
そして、4が、アジャイル開発の中では必須の大きな位置を占めるようになってきた。テストコードとプロダクトコードを対にして維持し、テストを設計に持ち込んだ(TDD)のはアジャイルの功績だ。
5も、名前付けなどと関係して昔からある。最近FluentInterfaceや動的言語の登場で価値観が昇格しているが、特に関数型言語など、うまく使うと言いたいことを「そのまま」ぱしっと表現できた!と感じる瞬間があり(浅海智晴さんが、terseな表現、という言い方をしていた)、これは、5の新しい形だろう。(※1/5追記 思考と言語表現のS/N比が高い、ということもできる)
また、1, 2, 3 は、ASoC(Advanced Separation of Concerns)とも関連していて、例えばAOPの出現で、散らばった log を一箇所にまとめることができたりするようになってきた。また、メタプログラミングや属性(アノテーション)などの手法もこの目的に使うことができる。
このように、1-5は昔から「よい設計」を表現しているのだが、ここ10年で新しい手法を伴って繰り返し認識されている指針なのである。このような、「よい設計とは」、をUncle Bobはオブジェクト指向の原則として10数個にブレークダウンした。(『アジャイルソフトウェア開発の奥義』)ぼくはこれが現在もっともよい設計原則集だと思っている。
(※年末、ThoughtWorks Anthology(『ThoughtWorks アンソロジー ~ アジャイルとオブジェクト指向によるソフトウェアイノベーション』近々に書評書きます) を読んでいたら、これに「フォーカス」、という概念が追加されていた(Alan Shalloway)。これは、1と良く似てはいるが直行する概念だということだが、1と2の組み合わせで説明できる概念だとぼくは思うので、ここでは割愛。)