メソッド屋のブログ

米マイクロソフト DevOps エバンジェリスト 牛尾の日記です。ソフトウェア開発の上手なやり方を追求するのがライフワーク。本ブログは、個人の意見であり、所属会社とは関係がありません。

「それ、アジャイルできてへんのちゃいますか?」チェックリストの公開

 DevOps を導入して、リードタイムの短縮などの効果を出したい時に、前提条件となっている「アジャイル」がまだ導入できていないケースが多い。そういったケースでは、まずアジャイル導入のご支援をすることもよくある。

f:id:simplearchitect:20160923161901j:plain

 そういった支援に入ると、「アジャイル導入前提」で構成されたはずのプロジェクトであっても、全然「アジャイル」のポイントを外しているというケースは珍しくない。更に問題なことに、「アジャイルをできます!」と言っているベンダーさんを連れてきても、全然ポイントを外しているというケースすら珍しくない。今回のブログではそういったケースでも、簡単に確認できる、「アジャイルになっていないかもしれない簡単なチェックポイント」を対策付きでいくつかご紹介しよう。  スプリントの中で、ウォータフォールを実施するのではない。それはミニウォータフォールというバッドプラクティスだ。

1. 進化型設計ができていない

 アジャイル開発を実施するということは、単に繰り返し型で開発すればいいものではない。アジャイルは「変化に対応する」ことが大きな目的の一つになっている。スプリントや、イテレーションで繰り返し型の開発を行う場合、繰り返し型で開発を行って、変化があっても、メンテナンスを実施しやすいコードベースをキープしないといけない。  そうでなければ、早晩、プロジェクトはメンテ不可能になって破たんする。スプリントを通して、変化を受け入れても、メンテ可能な状態を保つには、十分な自動実行できるユニットテストが書かれている事、変更があったときに、それが自動で検査されること、そして、設計が「変化前提」の方式になっているということが重要だ。

 こういったアジャイルにおける「テクニカルプラクティス」やその「マインドセット」を学ぶには、Extreme Programming を学ぶのが一番おすすめだ。更に高度なテクニカルプラクティスを学ぶには、DevOps のプラクティスを学ぶとよい。

 アジャイルは世界的にスクラムが最も流行っているが、スクラムの作者も、「テクニカルプラクティス」を軽視しているわけではない。確か、Ken Schwaber がQ&Aでこんなことを言っていた。

Q: スクラムを採用しているが、エンジニアリングがちゃんとできないメンバーだったらどうなりますか?

A: うん。10倍のスピードでものができるよ。ただしゴミだけどね。

 スクラムを回していても、ソフトウェアを開発しているケースでは、「テクニカルプラクティス」を無視してしまうと、非常に危険なこと になる。

1.1. テスト駆動開発

 まず、最初におすすめしたいのが、テスト駆動開発(Test Driven Development) もしくは、振る舞い駆動開発(Behavior Driven Development) で開発するのをおすすめしている。最先端での議論では、TDDは死んだと言っている向きもあり、すべてをそれで開発しなくてもいいが、このいづれかの開発スタイルが「やろうと思ったら出来る」ということは絶対的に重要だ。だから、これが「できない」と言っているアジャイルベンダーは「エセ」といっても差し支えない。変更があったら当然テストが必要だが、変更が当然のアジャイルで、変更の度に全量手動テストなんてやってられないだろう。

 十分な単体テストを書こうと思うときに、後追いで、ユニットテストのコードを書くと死ぬほど難しく、複雑になる。本番のコードは甘くないのだ。じゃあどうする かというと、少しだけ先に「テストコード」を書いて、テスト実行。エラーになったのを確認してから、本番コードを数行実装、テストを実行してパスしたら、次のテストコードの実装を少しだけ、、、更に、コードが重複したら「リファクタリング」という方法でコードの設計を改善する。  このようなステップを踏んで開発をすると、常にテストコードが十分な状態で無理なく開発を進めることができる。イメージがわきやすいようにビデオを作成したので、参考にされるとよいかもしれない。15分程度だ。

docs.com

1.2. 進化型設計 

   次に進化型設計アジャイル以前の世界の設計の考え方は、Big Desgin Upfront という設計の方法だ。時間をかけて分析、設計を行って、そのあと実装やテストに入る方法だ。一方、アジャイル以降は、進化型設計と言われる方法をとっている。ソフトウェアエンジニアリングの技術、例えばデザインパターンなどの知識が変わるとかそういう話ではないが、設計の進め方が変わる感じだ。これは、次のようなパラダイムの変更が影響している。

f:id:simplearchitect:20160923162637p:plain

この図はExtreme Programmingから紹介された概念だ。1つの変更に対してどの程度変更のコストがかかるか?という図になっている。ウォータフォール開発時代は、一つの変更に対するコストは、後のフェーズに行けば行くほど指数関数的に高価になってしまっていた。例えば要件定義フェーズで問題を発見したら、要件定義書を直すだけだが、テストフェーズで発見したら、実装をおなして、設計書を書き直して、要件定義書を、、、といったように非常に高くついてしまう。  だから、要件を固めよう!ということを一生懸命やっていたのだ。一方アジャイルの世界では、テスト駆動開発などで適切に自動テストが書かれており、継続的インテグレーションにより、それが常時結合されて、テストされており、なおかつ、「進化型設計」を用いて、変更が簡単にできるのであれば、開発の後半になっても一つの変更に対するコストがあまり変わらないという状態を創れるようになった。

f:id:simplearchitect:20160923163844j:plain

Big Design Upfront で設計している場合、最初の設計で想定していない変更が入ると、どんどん設計は崩れていく。そもそも、設計に長く時間をかけても、現在のソフトウェアは実装するまで本当のところがわからないケースが多いため、実装せずに設計するのは相当に難しいことだ。一方、進化型設計は、テスト駆動等を用いて、テストがある状態をキープしているので、変更を行っても、おかしくなったらすぐわかるし、DRY(Don't Repeat Yourself)をはじめとしたマインドセットでコードが作られていると、1箇所変えるだけで変更ができるので、こういった、コストカーブが実現できるようになる。だから変更に強くなる。

 ということは、そういうことをしていなかったら、いくらアジャイルっぽくスプリントを回したところで、ソフトウェアはその変更に耐えられなくなってしまう。だから、テスト駆動などの方法を学んで、常にクリーンコードを書くことを実践しないと、あなたのコードベースは遅かれ早かれメンテ不能に陥ってしまう。

マーチンファウラー氏の進化型設計のページ

 こういったことは、ツールをいくら導入しても解決できない。これは「開発の習慣」だから、本を読んでもすぐにできるわけでもない。じゃあどうするかというと、本当に「テスト駆動などの開発習慣を何年も当然として実施できる」メンバーを開発チームに入れるのだ。これは数カ月でもいい。本で読んでもすぐわからないかもしれないが、そういう「イケメン」と一緒に開発をすると、「あーこうだったのか!」と簡単に理解できる。ただ、こういう「技術イケメン」は普段あなたがお付き合いしているベンダーにはいないかもしれない。実際問題として、できないベンダーでも受注するために「できます!」というケースもあるし、自分が「できない」ことに気づいていないベンダーさんも多い。これを、一人で見分けるのは最初は難しいかもしれないが、シンプルな方法としては、アジャイル系のイベントに参加して、スポンサーセッション以外で登壇している人を捕まえて、その人に、「テスト駆動をホンマにできる人紹介してくれませんか?」とお願いしてみよう。そしたら、本当にそういうことができるベンダーさんを教えてくれるだろう。アジャイルができる人は、ちょっと話をしたら、誰がちゃんとできるかもわかるものだ。   もしくは、t-wadaという男を見つけて、彼にしっかりとした対価をお支払いするのがいいかもしれないw (注:TDDと言えばt-wadaと言われる日本のテスト駆動の大家ですw)

twitter.com

もちろん私に聞いてもらっても結構だ。

1.3. スプリントはミニウォーターフォールではない

 よくある誤解で、スプリントの内部はウォータフォールになっているというのがある。実際はそうではない。進化型設計で開発すると、「要件ー>分析・設計ー>実装ー>テスト」という順番で物事は進まない。

f:id:simplearchitect:20160923170842j:plain

先ほどのテスト駆動開発だって、そもそも実装の前にテストであり、実装をした後にリファクタリングで「設計」変更を行う。進化型設計とは、常に設計をしているような状態だ。実際に実装してから、ユーザさんに見せると、「あーイメージが違うよ」となるかもしれない。それは要件を確認している行為だろう。  つまりアジャイルの開発では、要件、分析、設計、実装、テストはいったり来たりする感じで開発されるので、シーケンシャルに流れるものではない。だから、もしそうなっていたら、ミニウォータフォールと呼ばれるバッドプラクティスに陥っている可能性が高い。これも、先ほどの「良い開発習慣を持った人をチームに雇う」ことが最も良い解決策だと思う。 

2. ビルドが中心になっていない

 次によくありがちな状態としては、開発のスケジュールが決まっていて、機能1を第一スプリントで、機能2を第二スプリントで、、というような形態になているケース。

f:id:simplearchitect:20160923164229j:plain

これは何が問題か?というと、アジャイルの考え方では、「動作するアプリケーションで物事を判断する」ということがある。例えば、機能1ができて、機能2ができてから、機能3を作ってやっとお客様に見せて価値があるとかいうスケージュールになっている場合が多い。でも、それだと、第三スプリントが終わるまで、仕掛品を作り続けていることになり大変危険だ。アジャイルの場合は、最初のスプリントから、価値の出る単位で、開発していこう。別に「最終製品」のクオリティが実装されていなくてもいい。 最初のうちに必要なのは、価値の出る単位ものが、つながってビルドとなっているかだ。仕掛品は、つなげてみるまで結局本当にできているかはわからない。だから小さくてもいいし、機能がフルに実装できてなくていいので、つながっているものを創っていく。最初に作ったものがそのまま本番に使われると考えるよりも、最初のものは、アーキテクチャ的だったり、仕様的だったり、どれが正しいかを探索する実験のようなものだ。工数をかけず、さっとつなげて、ビルドをつくって、そこからフィードバックを得よう。だから、がっつり機能1、機能2を実装していくなんてことは、本当にそれでよいかわからないものに対して多大な工数をかけていくことに他ならない。 それは大変アジャイルの世界では危険な行為なのだ。まずそれがそのプロジェクトにとって「正しいか」を確かめよう。最小の工数で。

3. 予定の機能の実現がMUSTになっている

 さらによくあるのが、予定の作業をすべて実装しようとしているケースである。アジャイルでやったからといって、自動的にウォーターフォールに対して生産性が強烈にアップするだろうか?ポイントは、「無駄なことをやらない」ことだ。すべての機能実装を100%やって、それを劇的に早める方式などない。

f:id:simplearchitect:20160923171235j:plain

 しかし、実際のところ、機能のうち、本当に使われるものは、40%未満だ。それを考えると、使われない機能を実装しないだけで、生産性は倍になる。多くの人は、「たくさん早く実装する」ことがよいと思っているかもしれないが、ポイントは、「やらないことを見つける」事だ。そのためにアジャイルでは「スプリント」をつかって学びを得て、いかに少ない工数で、より高い価値を提供するかを追求している。ものをたくさん生産したらたくさん価値が出るわけではない。だから、最初に予定している機能を100%実装するということは、無駄を大量に実装していることになり、そんなことをしたら、アジャイルで開発しても全然価値が出ないことになる。

 たくさん機能を実装したら、たくさん価値が出るという考えを捨てることから始めよう。

simplearchitect.hatenablog.com

 こういう「マインドセット」は、プロジェクトの開始前に関係者にプレゼンテーションなどをしてシェアするのをおすすめしている。後出しじゃんけんになると、反発してくる人も多く出てくるが、始まる前で、かつアジャイルを導入しよう!と会社で決めているならば、皆さん喜んで学ぼうとしてくれる。アジャイルコーチを採用して、こういう事を最初の段階から共有するようにしよう。「シンプルさ」に関するマインドセットもExtreme Programming から来たものだ。

Do The Simplest Thing That Could Possibly Work

You Arent Gonna Need It

Once And Only Once

4. マネージャーの指示でチームが動いている

 最後のアンチパターンとしては、マネージャの人が、スプリントでの実施内容を決めていたり、マネージャの指示にしたがって、メンバーが動いているようなケースだ。

f:id:simplearchitect:20160923164915j:plain

アジャイルの場合は「自己組織チーム」といわれる考えでチームを運用する。チームに技術的決定や、タスクの分割、割り当て、見積もり、、などなど大きく権限を与えて彼ら自身が考えて判断するようにする。DevOps の時代でもそれが進化したフィーチャーチームという考えになる。そこには開発チームだけではなく、Opsのメンバ、テスター、プロダクトオーナーも含まれる。そういうチームにがっさりと権限を与えて、彼ら自身に判断してもらいながら、プロジェクトを遂行させる。  普段プログラムを書いていない人が、現在の流れのはやい技術の世界で正確な指示が出せるはずもない。諦めて、彼らに任せよう。もしかすると、受け身なメンバーを見ていると、任せるのが不安かもしれないが、任せて、メンバーも慣れてくると、生き生きと自分で考えて行動するようになってくる。最初のしばらくの辛抱だ。  そうやって、自己組織チームができてくると、上の人が判断していた時代と比べても、圧倒的に早く生産的でイノベーティブになることができる。

 任せる方法がわからない場合は、やはりアジャイルコーチをやとって、自己組織チームを構成するようにするとよい。組織的にそれが現在はできないって? 上に掛け合って実現しちゃえばいい。人事制度がって?変えればいい。やらなければ、生産性が相当わるくなって、チームがやらされムードに支配されてあまり生産的でもイノベーティブにもならないだけだ。

5. 日本の「常識」で考えている

 最後に、私の自戒も込めて。我々はどうしても、制約事項を「日本の常識」で考えてしまい、「これはできない」とか判断してしまいがちだ。しかし、アジャイルは西洋の人が考えたものなので、西洋の人の考え方を学べば、もともとどういう概念でそれが提唱されたか、どういう前提条件があるのかが非常に理解しやすくなる。

 これに関しては今すぐおすすめの解決策はなく、私のブログを読んでぐらいしかないのだが、現在Rochelle Koppさんという専門家の方と共に、そういった考え方を学びやすくする取り組みを始めている。しばしお待ちを。

おわりに

自分の経験ベースではあるが、日本の現場におけるアジャイルアンチパターンとその対策についてまとめてみた。より多くの人が、アジャイル開発を実施して、実際にそのメリットを享受できればという思いでまとめてみた。基本的には、ツールや方法を表面上インストールしてもたいした変化は期待できない。重要な事は、本質を理解しすること、それから、良い開発の習慣を身につけることだという理解を持つこと。考え方や、習慣はすぐには身につかない。だからこそ価値があり、効果がある。

少しでも皆さんの参考になれば幸いである。