アジャイル開発入門

## 背景

個人的な経歴としてこれまでウォーターフォール型の開発に多く関わってきたのですが、最近になってアジャイル開発の模範解答のような開発スタイルの現場に関わることができました。
そこで学んだ「アジャイル開発ってこういうものなのか」を記事にまとめます。
あくまでも一個人の解釈として読んでいただければ幸いです。

## そもそもアジャイル開発とは

アジャイル開発とは、システム開発における開発手法の1つ。
アジャイルという言葉を聞いたことがない、あるいは名前は知っているが詳しくは知らない、という方はまず以下の**アジャイルソフトウェア開発宣言**と**アジャイル宣言の背後にある原則**をお読みください。
どちらも1~2分あれば読めます。

https://agilemanifesto.org/iso/ja/manifesto.html

https://agilemanifesto.org/iso/ja/principles.html

アジャイル開発について解説されたサイトや書籍は多くありますが、結局のところそれらは全てアジャイルソフトウェア開発宣言の内容に集約されるものだと思っています。

その中でも特に重要だと思った部分を以下に抜粋。

>プロセスやツールよりも個人と対話を、
>包括的なドキュメントよりも動くソフトウェアを、
>契約交渉よりも顧客との協調を、
>計画に従うことよりも変化への対応を、
>価値とする。
> 
> *アジャイルソフトウェア開発宣言 より*

>動くソフトウェアを、2-3週間から2-3ヶ月という
できるだけ短い時間間隔でリリースします。
>
> *アジャイル宣言の背後にある原則 より*

要するに上記の内容に価値を置く開発が実践されていればその開発はアジャイル開発であり、そうでなければその開発はおそらくアジャイル開発ではない、ということです。

## ウォーターフォール型開発との比較

アジャイル開発の説明で比較対象としてよく出てくるのがウォーターフォール型開発。
本筋から逸れるのでウォーターフォールの細かい説明は省きますが、ウォーターフォール型開発では価値を置くポイントがアジャイル開発と対照的となるイメージです。

* （対話も大事だけど）プロセスやツールに重きを置く
* （動くソフトウェアはもちろん大事だけど）ドキュメントがきっちり揃っていることにも重きを置く
* （顧客と協調する事は大事だけど）事前に何をどこまでやるかを契約で決めておくことが大事
* （変化することもあるだろうけど）最初に計画を立てて計画通りに進むようにマネジメントすることを重視する
* （頻繁にリリースを繰り返すのではなく）ある程度完成して品質が担保された状態でリリースする

ウォーターフォール型開発はざっくりこんなイメージ。（もちろん、開発案件や組織によって重視するポイントは様々です）

ちなみにアジャイルとウォーターフォールは開発スタイルの違いなので、どちらかが優れている、劣っているのようなものではないです。
考え方や価値を置くポイントの違い。
開発するプロダクトやプロジェクトの性質によってどちらの開発スタイルが最適かは変わると思いますし、むしろ色んな開発手法の良い部分を取り入れながら開発現場に合わせて最適化することが大事だと思います。
なんでもかんでもアジャイル開発の方がよいわけではないのでその点は注意。

## アジャイル開発実現のためのキーワード

>プロセスやツールよりも個人と対話を、
>包括的なドキュメントよりも動くソフトウェアを、
>契約交渉よりも顧客との協調を、
>計画に従うことよりも変化への対応を、
>価値とする。
> 
>動くソフトウェアを、2-3週間から2-3ヶ月という
できるだけ短い時間間隔でリリースします。
>

繰り返しになりますがアジャイル開発の本質的な部分は集約すればこれだけだと思います。
文章にしてしまえばたったこれだけですが、たったこれだけを実現するのがそう簡単ではないことを今の現場で体感しました。

本格的にアジャイル開発を実現するために重要となる技術やキーワードを以下にまとめます。

* エンジニアと顧客のマインドと文化
* ペアプロとモブプロ
* TDD
* CI/CD
* DDD

最低でもこれらの技術や要素が盛り込まれていなければアジャイル開発の実現は困難です。

ここからは、アジャイル開発実現のためにそれぞれのキーワードがどのような役割を果たすかを説明していきます。

### プロセスやツールよりも個人と対話を

この文言の背景にあるのはおそらく以下の原則。

>情報を伝えるもっとも効率的で効果的な方法は
フェイス・トゥ・フェイスで話をすることです。

これを実現するには以下のキーワードがポイントになります。

* エンジニアと顧客のマインドと文化
* ペアプロとモブプロ

#### エンジニアと顧客のマインドと文化

システム開発の現場では顧客-エンジニア間やエンジニア同士でコミュニケーション不足による認識の齟齬が起こりがち。
些細な認識の違いでも後々大きな問題に発展することも少なくないです。
認識の齟齬を無くして本当に価値のあるものを顧客に届けるために、アジャイル開発ではとにかく対面でのコミュニケーションを重視します。

「コミュニケーションを大事にしましょう！」と言葉にするのは簡単ですが、実際にオープンかつフラットなコミュニケーションが定着した開発現場を作るのはとても大変です。
そのような現場を作るためにはまずエンジニア自身が関係者を巻き込んでオープンにコミュニケーションする姿勢が求められます。
そして顧客もまた、エンジニアと積極的にコミュニケーション取ろうとする姿勢が求められます。
そして何より、エンジニアと顧客それぞれの組織全体に対して「オープンでフラットなコミュニケーションが積極的に行われるべき」という文化が根付いている必要があります。

つまり、アジャイル開発ではエンジニアと顧客、それぞれにコミュニケーションに対するマインドと文化が求められます。
そのマインドと文化がなければアジャイル開発は難しいでしょう。

#### ペアプロとモブプロ

また、エンジニア同士が対話をしながら開発を進めていくためにはペアプロやモブプロといった開発手法を取り入れることも重要です。

ペアプロはペア・プログラミングの略で、2人1組で1つの画面を共有しながらプログラミングを行う開発スタイルです。
モブプロはさらに人数が増えて、3人以上で1つ画面を共有しながらプログラミングを行う手法です。

ウォーターフォール型の開発では、1人1人役割分担をして効率的に作業できるように計画を立てていくことが重視される傾向にあります。
一方のアジャイル開発では対話することを重視するので、ペアプロやモブプロを積極的の取り入れる傾向があります。

ペアプロやモブプロを取り入れることで、必然的に他の開発者と対話しながら作業を進めることになります。
その結果、エンジニア間での認識の齟齬を減らすことができ、ユーザーが本当に求めているソフトウェアを提供できる可能性を高めることができます。

### 包括的なドキュメントよりも動くソフトウェアを

この文言の背景にあるのはおそらく以下の原則。

>顧客満足を最優先し、
価値のあるソフトウェアを早く継続的に提供します。

>動くソフトウェアこそが進捗の最も重要な尺度です。

これはシステムを使うエンドユーザーにとってはとてもありがたい考え方です。
多くの場合、ユーザーにとって最も価値があるのは動くソフトウェアです。
ユーザーはシステムが正しく、かつ使いやすく動作していればそれだけで十分満足で、ドキュメントが正確に細かく整備されているかどうかについては興味はありません。
見たいドキュメントがあったとしてもせいぜいマニュアルくらいでしょう。
ドキュメントを作成することに多大な工数を割くのであれば、ドキュメントの作成を極力省いて動くソフトウェアを作る時間にあて、顧客に素早くソフトウェアをリリースしようと考えるのがアジャイルの考え方。
顧客の視点に立てばこの考え方は理にかなった自然な発想と言えます。

そこで1つの疑問が生まれます。
だったらウォーターフォール型の開発でもドキュメント作成を省いてソフトウェアを先に作ってしまえば良いのでは？？
そう思ってしまいますが、実際にはそんなことはせず、多くのウォーターフォール型開発ではたくさんのドキュメントを作成します。
もちろん、そうすることには理由があるからです。
大きな理由の1つは、ウォーターフォール型の開発ではドキュメントを正しく詳細に作ることでソフトウェアの品質を高めることができると考えているから。
実際、設計書などのドキュメントの質が高ければ、ソフトウェアの品質を上げることも楽になりますし、開発者が途中で変わる場合などの引き継ぎの作業も楽になります。

アジャイル開発では（ドキュメントを作ってはいけないわけではないが）ドキュメントを作ることよりも動くソフトウェアを作ることに価値を置きます。
では、ドキュメントがない分ソフトウェアの品質は落ちても問題ないのでしょうか。
もちろんそんなことはありません。
ユーザーに価値を提供することを重視しているはずのアジャイル開発において、システムの品質が悪くて使い物にならなくては本末転倒。
ドキュメントを作成することに工数は割きたくないが、品質を犠牲にすることもしたくない。
そのわがままを実現するためのキーワードとなるのが次の3つです。

* ペアプロとモブプロ
* TDD
* DDD

#### ペアプロとモブプロ

ペアプロとモブプロの説明は前述した通りです。

プログラムの品質を上げるための効果的な手法の1つは、コードをレビューすることです。
むしろ、ドキュメントがない状態で品質を担保するためにコードレビューは必須とも言えます。
ペアプロやモブプロを行えば、基本的に全てのコードが常にレビューされている状態での開発が実現できます。
1人で開発をするよりもバグを発見する確率が上がり、よりよい実装方法を思いつく確率も上がります。
モブプロとなれば人数が増える分さらに品質が上がることが期待できます。
ソースコードを常に複数人からレビューされている状態を作るために、アジャイル開発においてペアプロやモブプロは重要は要素となります。

#### TDD

TDDはTest-Driven Development（テスト駆動開発）のこと。
TDDをすごくざっくり説明すると、テスト用のフレームワーク（例えばJUnitなど）を使ってテストを先に実装し、テストが通るようにプログラムの実装を進めていく開発スタイルのことのです。

コードレビューする以外でシステムの品質を上げる方法はテストによって品質を保証することです。
とは言え、ドキュメント作成に重きを置かないアジャイル開発においてテスト仕様書を作ってテストする作業はできれば避けたいところ。
また、細かくリリースを繰り返すアジャイル開発において手動でテストを行うのはあまりに非効率、かつ品質の保証が難しくなります。

そこでアジャイル開発ではTDDによって自動化されたテストを用意することによって品質保証を行います。

また、ドキュメント作成に時間を割きたくないとはいえ、開発しているシステムのあるべき（仕様）が定義されていないのは長期的に開発・メンテナンスをしていく上で流石に困る場面も出てきます。
そこでテストコードでシステムのあるべきを定義することで、テストを参照すればシステムのあるべきが分かる状態を作ります。

#### DDD

DDDはDomain-Driven Design(ドメイン駆動設計)のこと。
誤解を恐れずものすごくざっくり説明すると、システムの仕様をコードで表現するための設計・開発手法のこと。

顧客に対してシステム開発をする場合、必ずそのシステムに対する固有の専門知識が必要になります。
例えば、ECサイトを作りたい場合、商品に関する知識や、物流に関する知識、売上に関わるお金に関する知識などが必要になります。
特定の業界に向けたシステムを開発する場合であればその業界についての知識が必要になるし、特定の企業に向けたシステムを開発する場合、その企業内での業務内容やルールについての知識が必要になります。
DDDの世界ではそのような特定の専門領域に関する知識をドメイン知識と呼びます。

エンジニアはプログラミングなどのIT技術に関する知識は持っていますが、顧客が求めるシステムに対するドメイン知識は有していない場合がほとんどです。
そのため、必要に応じて顧客からヒアリングをする中でドメイン知識を習得し、最終的にはシステムの実装に落とし込む必要があります。

ウォーターフォール型の開発であれば、そのようなドメイン知識はドキュメントに落とし込み、設計書という形でシステムへの実装方法を表現します。
一方でアジャイル開発ではドキュメントを作成することに時間は割きたくありません。
でも、ユーザーにとって価値のある品質の高いシステムを提供したい。
そこで登場するのがDDDです。
DDDを深く理解して正しく導入することで、ソースコードがドメイン知識をそのまま表現できるような設計と実装が可能となります。

>包括的なドキュメントよりも動くソフトウェアを

この1行を本気で実現しようと思うとペアプロ、TDD、DDDといった様々な開発手法を導入することが求められます。

### 契約交渉よりも顧客との協調を、計画に従うことよりも変化への対応を

この2つの背景にあるのはおそらく以下の原則。

>ビジネス側の人と開発者は、プロジェクトを通して
日々一緒に働かなければなりません。

>要求の変更はたとえ開発の後期であっても歓迎します。
変化を味方につけることによって、お客様の競争力を引き上げます。

これらを実現するには、以下の3つがキーワードになります。

* エンジニアと顧客のマインドと文化
* TDD
* DDD

#### エンジニアと顧客のマインドと文化

アジャイル開発を実践していく上では、エンジニアは顧客の立場を想像して価値あるシステムを提供するためにはどうするべきかを考え続けなければいけません。
価値を提供することを最優先して、過去に決まった仕様やこれまでの慣習に取られずに柔軟に施行していく必要があります。
そして顧客側もまた、エンジニアに歩み寄って対話を続けながらシステムについて考えていく必要があります。

これは責任を負うことを嫌がって決定権を相手に委ねたり、面倒を避けて指示されたことしかしないエンジニアでは実現できません。
また、顧客側がシステムに関することは全てエンジニアに丸投げするような顧客の場合も実現は難しいでしょう。
エンジニアと顧客の双方が相手の立場を想像しながら価値あるシステムを作るために自発的に動くことが求められます。
そして、チーム全体がそのような人物で構成されていることが必要です。

ウォーターフォール型開発の場合、上流工程で仕様を明確に決めることさえできれば、後の下流工程では指示されたことしかできないエンジニアで構成されていても成立するような開発スタイルですが、そうはいかないのがアジャイル開発です。

#### TDD, DDD

変化を受け入れて柔軟に対応することが大事だと言われても、動いているソフトウェアに対してガンガン変更を加えていくことは想像しての通り簡単なことではありません。
プログラムが後から変更を加えるのに多大はコストがかかるような設計になっている場合、その時点で変化を受け入れることは難しくなります。
また、プログラムに変更を加えたことによって既存の機能に影響を及ぼす可能性もあります。

ソフトウェアに対して変化を受け入れながらも、システムの既存の機能を壊さないための仕組みとしてTDDやDDDが大きく貢献します。
DDDによってドメイン知識をわかりやすく正確にコードに反映させることができていれば、後から変更が加わる場合も影響範囲を最小限にして柔軟に対応しやすくなります。
また、TDDによって既存機能に対するテストが用意されていれば、変更を加えたことで既存機能に影響があるかどうかも簡単に確認することができます。


### 動くソフトウェアを、2-3週間から2-3ヶ月という できるだけ短い時間間隔でリリースします

最後はこの原則について。
短い時間間隔でリリースを繰り返すアジャイル開発では以下を導入することが必須です。

* TDD
* CI/CD

#### TDD

TDDの説明は前述した通り。テスト駆動開発のこと。

短い間隔でリリースを繰り返すということは、動いているコードに手を加えることが頻繁に起こります。
動いているコードに手を加える場合、デグレが起きる可能性を考慮する必要があります。
新しいリリースの度に既存のコードが正しく動くことを保証するには、テストが自動化されている、かつ全てのコードに対してテストが存在していることが重要です。
そのため、TDDで開発が行われているかどうかは非常に重要です。

#### CI/CD

CI/CDはContinuous Integration／Continuous Delivery（継続的インティグレーション／継続的デリバリー）のこと。
CI/CDはビルド・テストの実行・本番環境へのデプロイ・などを自動化し、リリースまでの作業を少ない工数で実現する手法です。

システムのリリース作業は手動で行うのは時間がかかる場合が多く、ミスをすると最悪システムが動作しなくなるなどのトラブルも考えられます。
CI/CDを導入することでリリースまでの作業をスムーズになり、短期間でのリリースを繰り返すことが実現しやすくなります。
また、テストの実行が組み込まれていることにより、デグレが起きない仕組みを作ることができます。

## その他の原則について

*アジャイル宣言の背後にある原則* ここまでで紹介した以外にもいくつかの原則がありますが、それらの原則に対してもやはりこの5つのキーワードがポイントになると思っています。

* エンジニアと顧客のマインドと文化
* ペアプロとモブプロ
* TDD
* CI/CD
* DDD

例えば、以下の原則があります。

>シンプルさ（ムダなく作れる量を最大限にすること）が本質です。

この原則を実現するには、TDDで開発をすることがとても有効な手段となります。

## コミュニケーションツールについて

最後に1つ個人的な意見について。

>プロセスやツールよりも個人と対話を

アジャイルソフトウェア開発宣言の中ではこのように書かれています。
対話をすることはもちろん大事ですが、その中でどのようなツールを使うかは今の時代においてはかなり重要視するべき要素なのではないかと感じています。
物理的に同じ空間にいて対面でコミュニケーションを取ることができれば、恐らくそれが最も効果的なコミュニケーションですが、今はリモートワークも一般的な時代。
同じチームメンバーや顧客が物理的に離れた空間にいる場面も少なくありません。
そんな中で密に対話をしながらアジャイル開発をスムーズに進めていくには、便利なコミュニケーションツールを探して有効活用することが大事です。

現在関わっている案件ではコミュニケーションや情報共有のツールとして以下のツールを使っています。

https://www.gather.town/

https://slack.com/intl/ja-jp

https://miro.com/ja/

Slackは数年前から普通に使ってましたが、GatherとMiroは今の現場で初めて使用しました。
特にGatherはリモートワークしながらアジャイル開発を進めていく上ではかなり優秀なコミュニケーションツールであると感じています。

## まとめと感想

本格的なアジャイル開発を経験するまでは、アジャイル開発のイメージといえば「動くものを素早く作り、フィードバックのサイクルを何度も回す」くらいのイメージでした。
その認識は間違いではなかったのですが、その中で本当に顧客が求めているものを高い品質で提供していくためには、様々な開発手法を適切に組み合わせて実践する必要があり、技術的にも高いレベルが求められるものだと実感しました。

アジャイル開発を実践するには

* オープンかつフラットなコミュニケーションが出来るコミュニケーション力
* 顧客の立場を想像して顧客への価値を考えることができる想像力と論理力
* 慣習に囚われずに自分の頭で考えることができる自発性
* TDDやDDDを実践したり、CI/CDの構築ができる技術力
* 変化に対応して新しいものを取り入れようとするモチベーション

といった能力が求められると感じています。
そしてスムーズに開発を進めるためにはチーム全体がそのような能力を持っている、あるいは素質がある人材で構成されている必要があります。
そのようなチームを構成できるかどうかは、組織としてアジャイル開発を実践するだけの土台が作られていることが大事であると思います。
さらには顧客やユーザーが開発の立場に対して理解のある人達であることも大事です。

結論。
アジャイル開発は刺激が多く、学びも多く、やりがいも得やすい開発スタイル。
でも、本格的に実践して成果を出すのは結構大変。