KAKKA is not 閣下

Drivemodeというシリコンバレーのスタートアップでエンジニアとか組織開発とかしてたら、2019年9月に某自動車会社にExitすることになり、それからDX推進のリードを行っています。 CSP-SM(認定スクラムプロフェッショナル)、メタルドラマー。 ex:リクルート、ミクシィ、NAIST Twitter→@KAKKA_Blog

プログラミングまでインクリメンタルなソフトウェア開発

はじめに

TDDやインクリメンタルな開発について学び実践する機会があったので、今一度振り返り、記事にしておこうと思う。

ソフトウェアとして目指すべき所

ソフトウェアを開発するにあたり、このソフトウェアの目指すべき方向性とは一体なんなのかふと考え直す必要があるシーンに遭遇する。よくあるパターンでは、不確実な仕様を満たすことに注力したり、技術的品質に異常にこだわったりするあまり、"Things Right"なものにならない、またはなるのが非常に遅くなるパターンだ。もちろん言わずもがなそれは大事なことではあるが、そのソフトウェアが、必要とされるときに使われなかったら、それはただのToyとなってしまう。
世の中に広く普及しているソフトウェアで必ず共通しているものが、「価値がある」ということだ。しかし価値があるだけでは、数年間に渡りメンテナンスを強いられるようなソフトウェアになることだってある。これはビジネス上非常に苦しいことである。

f:id:KAKKA5:20200928095436p:plain

というわけでシンプルに考えると、ソフトウェアは「価値があり、品質が高い」というところを目指すべきである。かんたんに言うけれど、これはなかなか難しいことだ。しかし目指すべき所としては間違いない。ここに向かって走っていくべきだ。

ここでソフトウェアと言っているが、基本的にはソフトウェアに限らず、すべてのプロダクトは価値があり、品質が高いほうが良いということは間違いないだろう。しかし今回はレジリエント、スケーラブル、可観測性といった特徴を持つソフトウェアというプロダクトに対してフォーカスする。考え方そのものはソフトウェアに限らず有効に使えるものだ。

計画型プロセスと経験的プロセスによる不確実への戦い

なぜ使われないソフトウェアを作ってしまうのか。なぜ使われない機能に多大なコストをかけてしまうのか。その根本には要件定義書の不確実度にある。要件定義の精度を高めるという努力も一定効果がある一方で、要件が不確実なことがほとんどだからである。
f:id:KAKKA5:20200928101700p:plain
図で示すようなシンプルな領域については今回お呼びでない。「これは絶対に人々が求めるものだ!シンプルだ!」と思い込んでいるパターンも含め、それを示すデータやサイエンスがない限りたいていcomplexであり、我々の生きる未来そのものがcomplexであり、このchaosやcomplex領域において要件定義というものは単なる仮説にすぎない。
仮説ならばそれを検証しなければならない。いつやるのか?なるべく早いほうがいい。なるべく早く仮説を検証し、ゴールへの一歩を着実に積み重ねる必要がある。これができるのが経験的プロセスだ。
f:id:KAKKA5:20200928102424p:plain
仮説=真実という前提で歩みをすすめるのが計画型プロセスと言われる。
よってcomplexやchaosといった不確実な領域と戦うためには、様々な制約条件の中でも少なくとも経験的プロセスの考え方が必要となってくる。
これはすでに世の中に広く知れ渡っている考え方であり、かなり多くの組織で意識されていることだろうと思う。

Test Driven Development(TDD)でコードレベルの経験的プロセス

ソフトウェア・プロダクトの実態は≒ソースコードと考えることができる。ソフトウェア・プロダクトに対して仮説検証を繰り返す場合、ソースコードでも予めすべてを設計することは不可能である。よってソースコードレベルでのフロー効率を意識する必要がある。
f:id:KAKKA5:20200928112004p:plain
フロー効率を意識するとは、図のように一番早くプロダクト自体がShippableになる状態を目指すことである。これが冒頭で述べたインクリメンタルな開発である。高品質なソフトウェア・プロダクトを目指すのであれば、自動テストはなくてはならない存在であり、そしてフロー効率を考えるあれば、テストコードはタイムリーに書く必要がある。
テストコードをもっとタイムリーにしていくと、先に書いてしまったほうが良いのではないかとも考えられる。流動的な要件に対してそれを具現化したテストコードを書き(テストコード=仕様)、それをパスする実装部分をプログラミングする、さらに継続的にリファクタリングもする必要がある。これはフレームワーク化されており、みなさんご存知Test Driven Development(以下TDD)だ。TDDではTest→Code→Refactoringというサイクルを10分〜15分という非常に短い時間で繰り返しながらソフトウェアを開発していく。

Refactoringで経験的プロセスの考え方を活かす

Simpleな領域においての計画型プロセスの考え方では、プログラムの設計は早期に行われる。要件が固まっていればいるほど設計の抽象度も下がり、設計に従うことが正しく機能する。一方で不確実領域に対して経験的プロセスの考え方を導入する場合、早期に設計を行うことはどうしても抽象度が高くなる。よってプログラミングという具体レベルになると矛盾や無駄などが発生することは想像できる。この場合、設計はほどほどにしてジャストインタイムな設計・リファクタリングが有効に働く。これはシンプルに、開発途中のほうがコードへの理解、テクノロジーの知識が、開発前より高まっているからである。注意するべき点は、これができるのはRefactoringやTDDができる人だけであり、それができない場合、ただ設計をてきとうにやっただけ、ということになって終わってしまう。リファクタリングやTDDは単なる知識ではなく、習得にはそれなりに時間がかかる技術であるため、ソフトウェアエンジニアにはこれらのトレーニングの機会や実務で活かせる機会があると良いと思われる。

TDDはチームでの開発にフレンドリー

TDDは、極めれば極めるほど非常に透明性の高い開発プロセスである。Test, Code, Refactorというはっきりとした工程に加え、それぞれが非常に短い時間で行うため、誰かの頭の中でなにかしらの作業が行われているという時間が少ない。明確なプログラミングプロセスがソースコードにアウトプットされている状態である。これにより、ペアプログラミング、モブプログラミングなどの共同開発プラクティスにフレンドリーである。

終わりに

ソフトウェアは価値があり、品質が高くあるべきだ。不確実な領域との戦いを強いられる現代のビジネス環境において、フロー効率を考えた、早くShippableなプロダクトを開発できるインクリメンタルな開発によって、ソースコードレベルでも経験的プロセスの考えを生かしたプログラミングフレームワークは有効である。特にTDDなどは非常に相性が良いと思われる。継続的な設計、日常的なリファクタリングを繰り返すことにより、抽象的で無駄が多い設計から脱却し、それが高品質なソフトウェアへとつながる。
こういった内容は、Odd-e社におけるスクラムデベロッパーテクニカルトレーニングなどで学ぶことができる。スクラムの知識は必須ではあるが、ここから学べることはスクラムの範疇を超えており、不確実な要件、技術領域において価値のある品質の高いソフトウェアを開発するという観点において非常に役に立つ示唆がある。実務にもすぐに活かせるTDDの実践トレーニングも含まれている。