eyecatch
Thu, Apr 11, 2019

アジャイル開発の真髄 ― DRY

今携わっているプロジェクトではScrumで開発していて、私自身2年ほどスクラムマスタを経験した。 うちの会社はかなり保守的で、ごく最近までウォータフォールで開発するのがあたりまえだったので、そこから文化を変え、マインドシフトし、アジャイルなプロセスに順応していくにはそれなりに苦労があった。 今でも、アジャイルに慣れていないエンジニアがアジャイルなチームに入ってくると、やはりいろいろな違いに戸惑っているように見えるし、こちらとしても期待するアウトプットがなかなか出てこなくて困ることが多い。 私はスクラムマスタというロールを任されてはいるが、どちらかと言えばテックリードやアーキテクト的な役割に期待されている気がしていて、そっちに力が入ってしまうのが実情。 そんな状況なので、コードレビューには結構時間を割いているんだけど、アジャイルなエンジニアとそうでないエンジニアが書くコードにはなんだかとても重大な差異があるような気がずっとしていた。 で、最近それを説明できるまでに考えがまとまってきたので、ここに書き残しておく。 (adsbygoogle = window.adsbygoogle || []).push({}); ウォータフォールの問題 ウォータフォール開発は以下のような特徴がある。 綿密な計画を事前に立てて、計画通りに開発を進めることを重視する。 機能設計 ⇒ 詳細設計 ⇒ コーディング ⇒ テストといった感じに、全体の計画を工程でフェーズ分けして、手戻りなく、一方向に進むことを重視する。 各フェーズでは全開発項目を並行して進め、ソフトウェア全体の整合性を取ることを重視する。 各フェーズで、包括的で完成されたアウトプットを作ることを重視する。アウトプットは各フェーズで詳細にレビューする。 綿密な設計ドキュメントを整備し、適時アップデートしていくことを重視する。理想的には、コーディングは設計ドキュメントをプログラミング言語に射影するだけの単純作業になる。 これはこれで、バグの少ないソフトウェアを、大人数で、非属人的に、低リスクで開発するのに向いた開発手法ではある。 しかし、設計ドキュメントの整備にかなりの時間がかかり、開発工程全体が長くなりがちなのと、動くソフトウェアが出来てくるのが開発終盤になってしまうのが欠点。 ソフトウェアがビジネスにおいて果たす役割がかなり大きくなった昨今では、ウォータフォール開発はビジネスのスピードや変化についていけない時代遅れの手法という評価になった。 代わりに台頭したのがアジャイル開発だ。 現代では欧米のソフトウェアプロジェクトの9割以上がアジャイルなプロセスを採用しているというのをHPEのカンファレンスで聞いた覚えがある。 いまだにウォータフォールを採用するのは、例えばNASAのロケット制御ソフトウェアみたいな、バグがあると数十億ドルと世界トップレベルの人材が吹っ飛ぶようなソフトウェアの開発プロジェクトだ。 (因みにNASAのコーディング規約は、再起関数禁止、静的に回数が決まらないループ禁止など、常軌を逸した厳しさ。) アジャイル開発のDRY ウォータフォールとアジャイルの違いは大量にあるが、パッと見て分かりやすい違いは設計ドキュメントの有無であろう。 アジャイルな開発では設計ドキュメントを排除するのが基本。 ウォータフォールなプロセス: ウォータフォール開発では、こんな感じにいろんなドキュメントを作ることになる。 加えて、ソースコードには大量のコメントを書くのが良しとされていた。(うちの会社だけ?) また、テストフェーズでは、何をどう操作して何をどう確認するという詳細なチェックリストを作り、経験の有無にかかわらずだれでも機械的に同じテストができるようになっているのが理想とされていた。(うちの会社だけ?) 沢山設計ドキュメントを書いても、結局顧客が手にするのはソフトウェアだけ。(ユーザマニュアルは別として。) 顧客が目にする唯一の「真実 (Truth)」は、インストールされて手元で動いているソフトウェアだ。 この「真実」の挙動や構造を説明するもの、つまり「真実の情報源 (Source of Truth)」はどこにあるか。 機能設計書や詳細設計書は言うまでもなく「真実の情報源」。 ソースコードのコメントも、どのような処理をしているのかを説明するものが多いだろうから、「真実の情報源」と言える。 ソースコード自体も、「真実」の挙動を決定づけるものなので「真実の情報源」だ。 テスト設計書やチェックリストも、「何をしたとき、どうなる」ということを記述しているので、「真実の情報源」になる。 このようにウォータフォール開発では、唯一の「真実」を様々な形で何度も表現することになるので、開発工数が膨らむことになる。 アジャイル開発では、これをプロセスにおけるDRY (Don’t Repeat Yourself)と断罪する。 つまり、「真実の情報源」が複数になることを悪として、「真実の単一情報源 (Single Source of Truth)」にしなさいと言う。 これには、ソフトウェアの挙動を変更したいときに修正すべき「情報源」を少なくして、修正工数を下げつつ、「情報源」間のずれによるバグを防ぐ狙いがある。 アジャイル開発プロセスにおける真実の単一情報源 アジャイル開発プロセスにおける「真実の単一情報源」とは何か。 それは、ウォータフォール開発における「真実の情報源」から何を削減するかという話になるわけだけど、結論は明らかだ。 絶対に捨てられないものが一つだけあるので、それ以外を排除することになる。 残すのは当然ソースコード(自動テストのコードも含む)。 ソースコードが無ければソフトウェアは動き得ないので。 アジャイルなプロセス: ソースコードが「真実の単一情報源」なので、それ以外の「真実の情報源」はDRY違反。 これがアジャイル開発で設計ドキュメントやテストドキュメントの作成を避ける理由だ。 ただし、注意すべきなのは、設計そのものを否定しているわけでも、設計の情報をチームで共有をすることを不要としているわけではないこと。 アジャイル開発は、それらを重要視しつつも、それらのためにドキュメントを作るという作業を排除した。 ドキュメントが無ければ、設計しても人に伝えられず、すぐに立ち消えてしまうように思われるが、アジャイル開発ではそれを別の媒体に記録する。 この媒体が何かというのも明らかで、ソースコードしか作らないんだからソースコードそのものということになる。 要するに、ソースコードを動く仕様書兼設計書にするということ。 日本人にとっては英語が母国語ではないので実感がわき辛い気がするが、ソースコードは割と自然言語を駆使して書いている。 プログラミング言語の機能やライブラリやフレームワークが強力になって、プログラミングパラダイムやコーディング手法の進化もあって、ソースコードは設計を伝達する媒体として十分な表現力を持つようになった。 アジャイル開発の現場でよく、ソースが仕様書みたいなことを言うのを聞くが、それは伊達ではなく、言葉通りの意味ということだ。 「アジャイル開発という名目を掲げて仕様書作成をさぼっているから、ソースコードを見て仕様を読み解け」などという開発者の怠慢・傲慢ではなく、「仕様書のように美しく読みやすく体系立ったソースコードを書きます」という決意表明なのである。 (因みに現実的には、ソースコード以外の「真実の情報源」を完全に排除できるわけではない。ユーザマニュアルが最たるものだし、設計ドキュメントに関しても、大域的な設計は別途簡単にでもまとめておいたほうがいい場合が多い。結局は理想のDRYと現実との間でバランスをとることが大事。) ソースコードを動く仕様書兼設計書にするには ソースコードを動く仕様書兼設計書にするために実践すべきことはたくさんある。 フォーマッタをかける 体裁が整っていないコードは読み辛い。 フォーマッタは、アジャイル開発の普及につれて、IDEが提供する補助的な機能の一つから独立したツールへ、さらにプログラミング言語の一部へと昇格を遂げた。 変数名、関数名を説明的にする 変数名や関数名などの識別子は、仕様書における用語であったり、章節のタイトルであったり、文の主語・目的語にあたるものなので、明確で、正確で、曖昧さが無く、一貫性があるべき。 例えば、tmpとかlistとかの何が入るかわからない変数名はよくないし、HTTPでデータを取得する関数にはgetXxxよりもfetchXxxの方がいい。 また、なでしこで書かない限りは英語で名付けることになるので、英語をしっかりリスペクトした名前にすること。 よく、複数の要素を保持する変数(i.e.