見出し画像

うつくしく作る

持続可能な開発を目指して

技術的負債という言葉がある。持続的に開発していく中で不可避的に堆積していく、理想的な状態との乖離だ。
循環的複雑度といった概念はこの負債を定量的に示した指標のひとつで、ご存知の方も多いかもしれない。https://jp.mathworks.com/discovery/cyclomatic-complexity.html

一昔前と比べるとCIのプラグインが循環的複雑度を計測してくれたり、便利な単体テストフレームワークが存在していたり、そもそも「技術的負債」というワードが浸透していたりして、少なくとも負債の返済ということにまったくの無理解というケースはずいぶん減ったのではないだろうか。

それにも関わらず、技術的負債について書かれたQiitaのエントリーは減ってはいない。肌感覚としても、まだこの技術的負債という存在は消えていない。
そこには様々な理由があるだろう、納期とのトレードオフや採用技術の陳腐化、ちょっとした気の緩み。
では、我々はどのようにして不可避的に発生したこの負債と向き合うべきなのか。また、どのように負債が発生する前に防ぐのか。

先に断っておくと、私は単体テストの信奉者である。なので視点には多分の偏りがあるが、単体テストという営みを通して技術的負債とうまくやっていけるという信念がある。今日はそういう話だ。

単体テストの強みは品質担保ではない

「テスト」という響きから、単体テストというものは「品質担保」を至上命題としたものだと思うかもしれない。
そういった側面もあるが、どちらかというと「全力で実験するための命綱」という側面が大きい。
特にアジャイルの文脈、固定されたタイムボックスの中で施策を行い効果測定する環境ではそうだ。
この考え方の違いは意外と重要で、前者の考え方だと「もうリリース済だからうちのプロダクトには関係ない」「テストしたほうがいいのはわかっているけどコストがリターンに見合わない」という反論を許すことになってしまう。

プロダクトを作るプロジェクトは、常に前を向いているべきだ。

もうリリースしたからテスト不要、ではなくこれから新しい価値を生み出すためにテストが必要なのだ。

うつくしく繕う

テスト保護されたコードでは、原理的にはいかなる冒険も可能である。
一方で、昔から存在している「秘伝のタレ」コードはテスト保護されていないことが多い。
なんならテストしづらいI/Fで、テスト保護しようとすると大幅な改修が必要となるかもしれない。

ここで、多くの場合は「コストに見合わない」となってしまい、サグラダ・ファミリアのようなレガシーが誕生していく。

本当にもうメンテナンスしないことが約束されているコードであればよいが、凍結を約束してもOSのアップデートが必要だったり、なんやかんや要望がきたりして何かしらの変更が加わることは事実としてある。
理想的には作り直しかもしれないが、凍結が議論されるようなコードは作り直しに必要なドキュメントなど残っていないだろう。

そこで我々が取りうる作戦としては以下のようになるのではないか。
・システムレベルでがんばってカバレッジを当てるコードを書く
・ある時点のシステムをリファレンスとし、ひたすら本番ログを流し差分がないかチェックする

これは正直、かなり大変だ。が、システムのおかれた状況によってはこの対応が必要となる場合もあるだろう。考えたくもないが複雑度100を超えるようなコードがある場合、このような力 is Powerな方法が意外と有効だったりする。

もう少しライトな方法であれば、影響範囲の小さい下部コードからテストをやりやすい形にインターフェースを切り出していくというのもある。
インターフェースを作り変える時点ではテスト保護されていない、というのがリスクだが、肌感覚として複雑度30程度まではこの方法でやってもほぼリスクが顕在化することはない。

うつくしく作る

なぜI/Fに手を入れてまでテストをしたいのか。
それは、ひとえに「うつくしく作る」ためだ。
テスト保護することで安心して設計を見直すことができる。これは一時的なものではなく、永続的見直しが可能になることを意味する。
もちろん、I/F自体を変えなければいけない場面にも出くわすだろう。そんな場合であっても、複雑さが抑えられた形であれば低いリスクで作り変えられるだろう。
また、人間にとって直感的で、かつ拡張性に富む設計になっていれば開発ベロシティにもよい作用をもたらす。これは最初からベストな解でなくとも、テスト保護に背中を預けてカイゼンを続けていくことでたどり着くことができるだろう。
そしてなにより、きれいな設計・コードはエンジニアの精神衛生上よろしい。

単体テストは最高の「ふりかえり」

アジャイル開発を行っている方であれば、「ふりかえり」は当然のように開発プロセスに組み込まれている。
しかしこのふりかえり、多くの場合はスプリントの終端に配置されており、つまり週1くらいの頻度での実施となる。

一方、単体テストはデプロイごとに実施される。
試したことに対してすぐさまフィードバックが来る。
主観が廃された、残酷なまでにリアルなフィードバックだ。

単体テストを通して開発方針や日々の開発などを見直す、ぜひ試してみてほしい。

ただしく、たのしく、うつくしく

ここで語った「うつくしくつくる」、よい設計で、テスト保護されており、よいコードで作られているということはもちろん重要だが
大前提としては「ただしい」もの、つまり誰かの課題を明確に解決するものであるべきだ。
そして、できることならば「たのしい」開発をしたい。
そこらへんの話はまた別途するとして、「うつくしく」つくるための考え方や少しだけ具体的な方法を紹介した。

この記事が気に入ったらサポートをしてみませんか?