変化に強いソフトウェアを作る

ソフトウェアは新規開発中はもちろん、本番稼働中にも継続してできるだけ変更に強い必要があります。ビジネスが変化に対応する必要があるためです。すべてのビジネスは生き残るためにソフトウェアを上手に作り、運用しなくてはならなくなっています。

エラー危険

変更のコストは高い

ソフトウェア業界は全体としてコードの保守性に重きを置いてこなかったため、結果として、最初に開発に使ったよりもはるかに多額のコストと努力をソフトウェアの保守に費やすことになっています。

ソフトウェアが使われているのであれば、変更は避けられず、誰かが実際にコードを変更することになります。

機能追加はよくある要望の一つですが、最近になるまで、業界は適切に機能追加を行う方法を持っていませんでした。コードを保守しているチームは、多くの場合、最初にコードを開発したチームではなく、仮に機能拡張を頼まれたのがもとの開発者だとしても、どういう理由で現在の設計になっているのかを思い出すのは困難であるためです。

多くの場合、開発者はコードを書くよりも、読むことに多くの時間を必要とします。そのため変更が大規模な場合は、現状のコードを読んで理解する手間をかけるよりも、その部分を書き直そうとするのです。既存の設計を理解するのではなく、自分たちの方法で要求された機能を継ぎ足してしまおうとするチームが多いのです。その結果、システム全体の品質は低下し、以後のコードの拡張は更に難しくなります。

ほとんどのソフトウェアは機能拡張をうまく扱えるように設計されておらず、機能追加には再設計が必要となるので、リスクが高くコストも高いです。

そのため開発者は、既存コードは触らずに追加することもあります。いろいろなところで絡み合いやすいソフトウェアの性質は、ドミノ効果なしに機能追加するのを難しくしています。新機能が新しいバグを生み、さらに別のバグを生んでいく。それを直すとさらに別のバグが生まれ、それが続いていく...ということも珍しくありません。

バグの修正

ソフトウェア開発プロジェクトが失敗する理由の多くはバグにあります。バグ修正のコストは高いです。開発コストを幾何級数的に増加させ、プロジェクトを止め、システムをダメにします。

実はソフトウェア開発者でバグ修正に多くの時間を費やす人は少ないです。バグの中には有害で修正に時間がかかるものもあるが、多くは些細なものなのです。それにも関わらず些細な問題で済まないのは、まずバグを見つけるのが難しいのです。

2013 年時点で MacOSX にはおよそ 8,500 万行のソースコードが含まれていたのですが、それはたった一つのタイピングミスでクラッシュさせることができてしまいます。バグにはいろいろな種類があります。コンパイラが見つけられないタイピングミスのような小さなものから、システム全体の設計の欠陥のような大きなものまで、全てがバグに含まれます。

バグは氷山の一角にすぎないことが多く、その場合一つのバグを直す間に、ほかの複数のバグを直すことになります。ソフトウェアの構造は絡み合っていることが多く、一つのバグを直すともぐら叩きのような状況に陥ります。数分で直ると思っていた修正が、システム全体に到達する変更の波となることもあります。

つまり、本当に解決すべき問題は「どうやったらバグを見つけやすくできるか?」という点にあります。

小さく作り、ユニットテストを書け

私達の答えはこれです。

「テストはバグが存在しないことではなく、バグが存在することを示すものである。」

テストコードは新機能などを追加したときに、他の機能に影響なく動作するかを確認するものであり、 テストコードが存在しない場合は、「検品されていない商品が売り場に並ぶこと」と同じ状態になります。

エラーに気づかないだけで、表面には見えないエラーが裏にはたくさん潜んでいる可能性もあり、 どんなエラーがどこで起こるかを事前に検知することができません。

部品を小さく作り、その一つ一つにユニットテストを書き、動作保証をしましょう。 動作を確認しながら進めるため、エラーが起きた際の探索範囲を狭めることができ、エラーへの対処スピードが上がります。 また、エラーが連なってしまうドミノ効果も極力抑えることができます。

あとから品質を上げようとすると、最初から品質を作り込むのに比べると何倍ものコストがかかるものです。 一見コストが高そうに見えるユニットテストの用意ですが、運用が長くなればなるほど効果を発揮し、 運用期間中の変化に即対応していけるコードベースを保つことができるため、最終的にはコストを抑えながらも 今まで難しかった持続するビジネスアジリティを手に入れることができます。

SOULs では一つ一つの動作が確認できていれば全体が動作するよう設計し、 かつ Scaffold 時にテストコードを自動生成させているため、安全かつ迅速にソフトウェアを構築することができます。