Technical Information
質とスピード
~ソフトウェア開発の典型的な誤解を解く~
多くのソフトウェア開発現場では、「質とスピード」はトレードオフの関係にあると考えられています。両者を共に高めることは不可能であると。別の言い方をすると、片方を下げれば片方は上げられるという認識です。本講演では、これが果たして真実なのかを検証し、その実態を明らかにしていきます。
※この記事は、『ベリサーブ アカデミック イニシアティブ 2022』の講演内容を基にした内容です。
タワーズ・クエスト株式会社
取締役社長
テスト駆動開発者
和田 卓人 氏 
ソフトウェア開発における「荒ぶる四天王」
アジャイルソフトウェア開発の計画から実装までを1冊にまとめた『アジャイルサムライ』という本。ここには「荒ぶる四天王」というものが出てきます(図表1)。「与えられた時間に対してやるべきことが多すぎる場合、どうすべきか?」という問いに対し、敵として立ちはだかるのが「時間・予算・品質・スコープ」の4つで、以下のような対策が考えられます。なお、ここでいう「スコープ」とは、ざっくり「機能数」のことであると考えてください。
- a)スコープを削る - スコープとは機能数のことで、これをいくつか減らします。
- b)もっと人を増やす - 人員の増強で生産性を上げます。
- c)リリース日を延期する - 機能も人もそのままで、納期を延ばします。
- d)品質を犠牲にする - 機能も削らずリリースも動かさず、品質を落としてスピードを上げます。
私はソフトウェアエンジニアとして20年ほどさまざまな現場を見てきましたが、こうした厳しい状況で皆さんが選びがちなのが「d) 品質を犠牲にする」なのです。
では、本当に品質を落とせばスピードは得られるのでしょうか。これを考察するに当たり、以下のような仮説を立ててみましょう。
- 短期的には得られる?
- 中期的には逆効果になりそう
- 長期的には致命傷になる
短期的には得られるかもしれない、というのが大方の共通認識で、それがd)を選ぶ理由です。一方で、中期的には逆効果になりそうだというのも薄々感じていて、そして品質を犠牲にし続けると長期的には致命傷になるということも、実は誰もが理解しているのではないでしょうか。
品質を下げればスピードは上がるのか?
では、スピードを得るために犠牲にする「品質」とは何を指しているのでしょうか。以下は「ilities(イリティーズ)」、日本語では「○○性」と呼ばれる品質特性を並べたものです。実に多種多様で、この中のどれが犠牲になるのかを明確にしないと議論が混乱しそうです。
- Accessibility
- Adaptability
- Compatibility
- Configurability
- Exploitability
- Extensibility
- Flexibility
- Functionality
- Installability
- Integrability
- Internationalizability
- Interoperability
- Administrability
- Analyzability
- Learnability
- Maintainability
- Marketability
- Maturity
- Modifiability
- Operability
- Personalizability
- Portability
- Recoverability
- Reliability
- Auditability
- Availability
- Replaceability
- Reusability
- Scalability
- Security
- Sensitivity
- Stability
- Suitability
- Supportability
- Testability
- Traceability
- Calibrability
- Changeability
- Transactionality
- Understandability
- Upgradeability
- Usability
- ... and lots more!
■調整コストが低い内部品質が削られがち
これを整理するために、ソフトウェア品質の構造や関係性を理解する上で国際的なコンセンサスとなっている「SQuaRE」モデルを例にして考察してみましょう(図表2)。
図表2:システムおよびソフトウェア製品の品質要求・評価に関する国際的な規格である「SQuaRE」では、品質をこのように規定している
SQuaREでは、品質は大きく「利用時の品質」と「製品品質」に分かれ、さらに製品品質は「内部品質」と「外部品質」に分かれます。内部品質は保守性・柔軟性・可搬性など、外部品質は正当性・有用性・効率性などが該当し、両者は原因と結果の関係にあります。以下は、技術的負債を抱え込まないソフトウェア開発を指南する書籍『レガシーコードからの脱却』(David Scott Bernstein著)からの引用です。
「ソフトウェアの品質を外部指標で特徴づける人は多い。正しいことをする、バグがない、速い、などだ。だが、それらはより深い原因の症状にすぎない。
本書で説明するソフトウェアの品質は内部品質である。内部品質を作り込んだ結果として、外部品質として定義される特性の実現に近づくことができる。内部品質は結果ではなく原因であり、良いソフトウェアが備えているべきものだ。」
ここで、犠牲にされる品質とは何かを絞り込んでみましょう。まず利用時の品質と製品品質のうち、開発に関係するのは製品品質です。次に、製品品質を構成する内部品質と外部品質、つまり原因と結果では、原因である内部品質を犠牲にしようすることが圧倒的に多いと感じています。
なぜなら、内部品質の受益者もしくは被害者は開発チーム自身であるからです。自分たちが苦労することでスコープもコストも納期も動かさずに済むのなら(受け入れよう)、という思考です。他の品質を削るにはさまざまな人との調整が必要ですが、内部品質であれば短期的に自らが血を流すだけで済む、これを私は「調整コストが低い」と表現しています。
■「保守性」も犠牲にされがち
さらに、さまざまな現場を見てきた経験上、内部品質の中でも特に犠牲にされやすいのは「保守性」です。保守性は開発チームの生産性に直結する概念であり、かつ自分たちが苦しめば先を急げるかもという夢を抱きがちな特性でもあります。
SQuaREでは、保守性は以下の5つで構成されています。
- モジュール性
- 再利用性
- 解析性 ≒ 理解容易性
- 修正性 ≒ 変更容易性
- 試験性 ≒ テスト容易性
解析性は分かりやすさ、修正性は変更のしやすさ、試験性はテストのしやすさで、この3つは外部との調整が不要なため、真っ先に犠牲にされる傾向にあります。
■保守性を犠牲にするとどうなるか
次に挙げるのは書籍『Clean Architecture』(Robert C. Martin著)からの引用です。
「あとでクリーンにすればいいよ。先に市場に出さなければ!」
開発者はそうやっていつもごまかす。だが、後でクリーンにすることはない。市場からのプレッシャーは止まらないからだ。「先に市場に出さなければ」ということは、後ろに競合他社が大勢いるということである。競合他社に追い抜かれないためには、これからも走り続けるしかない。
その結果、開発者はモードを切り替えることができない。次の機能、また次の機能、またまた次の機能を追加することになり、コードをクリーンにすることまで手が回らない。
そして、崩壊が始まる。生産性がゼロに近づいていく。
身に覚えのある方も多いと思いますが、「後できれいにすればいい」というのはさまざまな現場で耳にする言葉です。実際には分かりやすさや変更のしやすさといった保守性を犠牲にして走り続けると、その後の不具合の修正や機能追加に余計な時間がかかり、徐々に生産性が下がってスピードが落ちていくことになります。
スピードを犠牲にしても品質は上がらない
一方で、もしも品質とスピードがトレードオフの関係であるなら、スピードを落とせば品質は上がるはずです。これに対する答えとして、『エンジニアリング組織論への招待』という本に「クイック&ダーティの神話」というものが出てきます(図表3)。
図表3:きれいなコードを書ける人がスピードのために汚いコードを書くことはない
ここでは、1人の人間が2つのモードを使い分けられるというのは「神話」に過ぎない、と喝破しています。冷静に考えれば、高い技術力を持つ人はある程度急いでも一定以上の品質のコードを書くし、意図的に品質を落としたとしても速度はあまり上がりません。逆に技術力の低い人が時間をかけても、実力以上のコードは書けないのです。
結局、保守性とスピードがトレードオフというのは思い込みに過ぎません。これを示したものが図表4で、スピードと質が白丸付きの矢印でつながっています。白丸付きの矢印は「負の接続」で、根元が増えれば先は減る、逆に根元が減れば先が増えるという関係ですが、保守性を落としてもスピードは上がらず、スピードを落としても品質は上がらないので、どちらの矢印も実は全くの誤解なのです。
■品質が上がるとスピードも速くなる
以下の文章は、再び『レガシーコードからの脱却』の引用です。
最高の開発者がいちばんきれい好きな開発者であることに気づいたとき、私はびっくりした。速いプログラマーは雑なプログラマーだと思っていたからだ。
だが、実際は正反対だった。私が会った中で最速のプログラマーは、コードを扱いやすいように保つことに特に注意を払っていた。
さらに続きます。
コードを書く速さとコードのきれいさに関連があると認識したあとでも、私はその2つの間の因果関係を見つけるのに時間を要した。
コードの品質を高く保っていた「にもかかわらず」速いのではない。コードの品質を高く保っていた「からこそ」速いのだ。
このことを理解したら、ソフトウェア開発に対する見方が変わった。
品質が低いからスピードが速いのではなく、品質が高いからスピードが速いというのが、正確な関係性であることが見えてきたわけです。
■スピードを落とせば品質も低くなる
我々は時間をかければ良いものができると思いがちですが、私の知人であるすご腕のプロジェクトマネジャーはこんなことを述べています。
品質は悪いと基本的に手戻りを生むので速度に跳ね返る。手戻っている時間は学びを生まない時間。品質を下げるという判断は学びの速度低下を許容するということ。
従来の鉄板(だと誤解されていた)だった「品質捨てて速度上げよう」は、品質は劣化すれば手戻りが発生するだけで、結局はリードタイムの増加に跳ね返るのでやめましょう。
ここでいう「学び」とは、優れたソフトウェアを作るのに必要な仮説検証プロセスを回す時間を意味します。現代のソフトウェアは、作って終わりではありません。むしろ作ってからが始まりで、どれだけの仮説検証プロセスを素早く円滑に回せるかどうかが競争力に直接関わってきます。
そのため、開発のスピードが落ちると仮説検証のプロセスが回らない、回らないと競争力のあるプロダクトを作るためのインプットがやってこないので、品質も上がらないのです。
品質とスピードの本当の関係
ここまでの検証を踏まえて、ソフトウェアの品質とスピードの本当の関係を記してみましょう。
- 内部品質がスピードを生み
- スピードが学びのループを生み
- 学びのループが外部品質を生み
- 外部品質が競争力を生み
- 競争力が売上を生み
- 売上が内部品質を育む
これを先ほどの図に置き換えると、品質とスピードは「正の接続」でつながることになります(図表5)。正の接続とは、根元が増えれば先も増える、根元が減れば先も減るという関係です。スピードが上がれば仮説検証を早く回して多くのインプットが得られるので、プロダクトの質を上げることができます。スピードを落とすと仮説検証を回せないので、結果的に競争力も落ちてしまうことになります。
最近出版された『Infrastructure as Code Second Edition』には、以下のような図が出てきます(図表6)。左にHi QualityとLow Quality、下にSlowとFastと並んでいますが、質とスピードのどちらかを落とした途端に「Fragile mess」に陥ります。Fragile messとは「壊れやすいゴミ」という意味で、片方だけを優先すると結局はゴミのようなソフトウェアを作り続けることになるわけです。
図表6:質とスピードのどちらかでも落とすと、ソフトウェアは壊れやすいゴミ(Fragile mess)になってしまうという痛烈な指摘がなされている
短期的と中期的の境目は?
ここまでの論考で、スピードを得ようとして犠牲にされる品質とは保守性であること、そして最初の仮説通り、保守性を落とすと中期的には逆効果となり、長期的には致命傷になることも明らかになりました。では次に、短期的と中期的の境目とはどこなのかを考えてみましょう。
短期的と中期的の境目とは、言い換えれば保守性に対する投資の損益分岐点です。先ほど触れた通り、保守性には理解容易性や変更容易性、テスト容易性などが含まれますが、これらに深く関わるのがテストの自動化です。保守性が高ければテストの自動化がしやすく、低ければテストは手動になります。手動テストと自動化テストの損益分岐点についてはさまざまな調査がありますが、多くの場合4回目のテストでコストが逆転し、以降は差が開き続けるというのが業界のコンセンサスになっています。つまり4回目のテストが短期的と中期的の境目になるわけで、意外なほど早いことが分かります(図表7)。
図表7:テストを自動化した当初は手動テストよりもコストがかかるものの、4回目のテストで自動化のほうが優位になる
さらに、Martin Fowler氏というコンサルタントが書いた技術文書では、設計やプロダクト全体の開発における内部品質への投資の損益分岐点は1カ月以内にやって来るとしています(図表8)。
図表8:Martin Fowler氏によれば、開発全体における内部品質への投資は1カ月以内に回収できるという
品質を犠牲にすると短期的にはスピードが得られても、やがて逆転してプロダクト全体に影響が出ることが分かっています。しかし、もしもそれが3年後だとしたら、プロジェクトが存続しているか、自分がこの会社に勤めているのかも分かりません。3年後の誰かのために質の高いコードを書くとなるとプロ意識や道徳、熱意に左右されますが、1カ月となれば自分自身の損得の話です。
ここで先の仮説に1つの結論が出ました。
- 短期的には得られるかも
- 1カ月以内には逆効果になる
- 長期的には致命傷になる
「中期的」というのは意外に早く、実は1カ月以内にやって来ます。つまり犠牲者も受益者も自分自身になるわけですから、誰もが真剣に考える必要があるのです。
おわりに
「質とスピードはトレードオフの関係にある」というのは大きな誤解です。スピードの対価として犠牲にされるのは主に保守性ですが、実際には保守性を落とせばスピードは下がり、保守性を高めればスピードは上がります。 逆にスピードを落としても保守性は上がりませんし、仮説検証プロセスが回らなくなってしまいます。
短期的には品質を落とすことでスピードが得られたとしても、わずか1カ月後には逆効果となり、その負債は開発者自身に降りかかってきます。そして長期的には、スピードも品質も低下してしまうのです。
最後に、「荒ぶる四天王」の答え合わせをしておきましょう。結論としては、正解が2つ、不正解が2つです。「d)品質を犠牲にする」が不正解なのは明らかになりましたが、もう1つの不正解は「b) もっと人を増やす」です。人を増やしてもスピードは上がらないことは、ソフトウェア関連書籍の古典といえる『人月の神話』(Frederick P. Brooks, Jr.著)が発行された50年近く前から周知されています。
私の見解では、「a) スコープを削る」もしくは「c) リリース日を延期する」、この2つが正解です。どちらを選ぶかはビジネス上の決断ですが、推奨されるのは「a) スコープを削る」です。なぜなら、ある一定期間にどの程度のものを作れたかが開発チームの生産性を見積もる指針になるからです。期間を増減してしまうと見積精度が低下することになりますし、そもそも締め切りを延ばしたところで新たな期限内に完成できる確証もありません。機能を減らして開発ペースは一定に保つ、つまり「a) スコープを削る」を、荒ぶる四天王と戦うための模範解答としておきたいと思います。
この記事をシェアする