ソフトウェア開発プロセスを学んで健康的なエンジニアライフを送ろう

# ソフトウェア開発手法について学ぶ

ソフトウェア工学を独学しております。
間違っている点等ございましたらコメントしてくださいますと非常にありがたいです。

## 目次

1. ソフトウェア工学の概略 
2. ライフサイクルモデル
3. アジャイル開発


## 1. ソフトウェア工学の概略

ノイマン式コンピュータが生まれた1940年代から、ソフトウェアに対する社会的な需要は爆発的に拡大した。しかしそれまで存在していなかった「ソフトウェア開発」というものに対する経験や知識は当然成熟しておらず、需要に対する開発速度及び品質の低さが問題となる。その歴史的文脈から1960年代にソフトウェア工学という工学が生まれ、ソフトウェア開発に関する技術が研究され始めた。

ソフトウェア工学の中で、様々なソフトウェア開発方法論(SDM)が発明/定義された。構造化プログラミング、オブジェクト指向プログラミング等の考え方及び技法がこれにあたる。

SDMの研究と共に(正確には相互的に内包された研究として)、システム開発ライフサイクル(SDLC)という概念が生まれた。これは**開発計画から設計実装運用保守、そして廃棄までの過程を標準的なモデルとして示したもの**である。

以下、条件付けせずにライフサイクルモデルと記載した場合、SDLCについて言及したものであるとする。


**参考資料**

* [ソフトウェア工学 - 玉井哲雄 2003年](http://tamai-lab.ws.hosei.ac.jp/pub/sebook.pdf)

* [システム開発技法の歴史 - 木暮仁](http://www.kogures.com/hitoshi/history/system-kaihatu/index.html)

* [ソフトウェア開発方法論 - wikipedia](https://ja.wikipedia.org/wiki/%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E9%96%8B%E7%99%BA%E6%96%B9%E6%B3%95%E8%AB%96#%E5%85%B7%E4%BD%93%E4%BE%8B)

## 2. ライフサイクルモデル

以下、代表的なライフサイクルモデルを列挙する。

-----


### ウォーターフォールモデル

システム開発における各工程を、水が流れるように順序立てて進めていく開発手法である。

基本的に工程を後戻りさせることはせず、下記のような流れでシステム開発を進行させていく。

![ウォーターフォール図](http://sysdev.sakura.ne.jp/wp-content/uploads/2014/07/7db1d37a96ad4e4bbfaf9f17c0a20b47-1024x677.jpg)

(引用元:http://sysdev.sakura.ne.jp/development/169)

また、昨今ではウォーターフォールはV字型の図で解説されることが増えた。

内容としては同一で、どの工程がどの工程へ対応しているかを強調する目的で表現を変えているだけのものである。


![V字フォーターフォール図](http://sysdev.sakura.ne.jp/wp-content/uploads/2014/07/e3690453026c34cfc85b0fc83d7bf9c1.jpg)

(引用元:http://sysdev.sakura.ne.jp/development/169)


**メリット**

* プロジェクト計画の見通しを立てやすい
* 要求定義/要件定義及び設計が先に完了するため、開発者の迷いを減らせる
* 適用開発例が多く、参考になるプロジェクトが多い
* 各工程での成果が明確になる
* 進捗管理がしやすい

**デメリット**

* 全工程を予め定義/作成しなければならないため、プロジェクト計画立案自体にコストがかかる
* 工程を後戻りさせることを想定させていないため、仕様変更があった際に多大なコストが生まれる


**どのようなプロジェクトに向いているか**

* 要求/要件/目標が固定されており、途中変更のないプロジェクト
* 予め全ての要求/要件/条件/期間/工程/責任を定義しなければならないプロジェクト
	* 発注/受注案件など。
		* 何が出来ていれば成約か、特に相互の責任を明確にすべき場合
* 期間的制約の強いプロジェクト

-----


### プロトタイプモデル(反復型)

プロトタイプモデルと呼ばれる開発モデルは、しばしば手法としてのプロトタイピングと混同される。

ここでは一般にプロトタイプモデルと呼ばれる開発モデルと、プロトタイピングを利用した開発を分けて考える。

まず、一般にプロトタイプモデルと呼ばれる開発手法の例を挙げる。

#### 一般的なプロトタイプモデル

* 立ち上がり期に機能を制限した実際の製品のプロトタイプを開発し、ユーザによる評価を受け機能追加/修正していくという手法
* 純粋なプロトタイプモデル(反復型)といえる

![プロトタイプ図1](https://thinkit.co.jp/images/article/914-101.png)

(引用元:https://thinkit.co.jp/article/914/1)

**純粋プロトタイプモデルのメリット**

* 計画立案時に全ての要件を作成するコストが発生せず済む
* ユーザとの認識のズレを最小限に留めることが出来るため、手戻りの際のコストが(ウォーターフォールモデルに比べて)低い
* ユーザ自身が当初想定していなかった要求に気づく機会がある
* ユーザがコア機能を早期に利用できるようになる

**純粋プロトタイプモデルのデメリット**

* 画面数や機能が多いプロダクトの場合、プロトタイピング工数自体がコストとなる
* 当初に要求/要件を明確にしないため、ユーザが満足するまでプロジェクトが完了しないリスクがある
	* 付随して、プロジェクト全体の見通しが立てづらい
* 評価者(ユーザ,ステークホルダ)の人数により、評価工程のコストが大きくなってしまう場合がある
* 評価者の選定が難しい

**どのようなプロジェクトに向いているか**

* 比較的小規模なプロジェクトに向いている
* 期間的制約の弱いプロジェクト
* 対象ユーザの課題が深刻であり、すぐさま改善を進めていきたい場合
* ユーザ自身が課題をどう解決していけば良いのか見通しが立っていない場合
* 評価者(ユーザ,ステークホルダ)が少ない場合


-----


#### プロトタイピングを開発工程に取り込む例

* 上と同様、機能を制限したプロトタイプを作成するが、要求/要件定義をする目的としてプロトタイプ利用し、その後本設計を開始するという手法。他の手法と併用される場合。

**要件定義のためのプロトタイピング利用手法**

![プロトタイプ図2](https://cdn-ak.f.st-hatena.com/images/fotolife/t/teeeeeeemo/20180220/20180220191611.png?1519121838)

**要求に対する提案のためのプロトタイピング利用手法**

![プロトタイプ図3](https://cdn-ak.f.st-hatena.com/images/fotolife/t/teeeeeeemo/20180220/20180220191608.png?1519121785)


(引用元:http://f.hatena.ne.jp/teeeeeeemo/20180220175918)

**プロトタイピングの目的**

* ユーザとベンダの間に想定のズレがないか早期に検知する
* 要求/要件の妥当性の検証
* 技術的実現可能性の検証

----

### スパイラルモデル(反復型)

ウォーターフォールモデルとプロトタイプモデルを併せた開発手法であると言われる。

しばしばプロトタイプモデル、インクリメンタルモデル(後述)と混同して語られることがあり、それらとの違いは理解が難しい。

特徴としては、**システムを複数のサブシステムに分割し、サブシステム毎にウォーターフォールモデルで開発を進めていく**という点。

サブシステム毎にプロトタイプを作成し、その後ウォーターフォールモデルで開発を行うという形。

また、サブシステムの**要求定義から評価(テスト)までを反復する**点にも注目しておきたい(後のインクリメンタルモデルとの大きな違い)。

![スパイラルモデル図](http://webpg014.hotcom-web.com/images/fig16.png)

(引用元:http://webpg014.hotcom-web.com/page6.html)

**メリット**

* 計画立案時に全ての要件を作成するコストが発生せず済む
* 一つ一つの機能(サブシステム)について、ユーザの満足度を高くできる
* ユーザが機能を早期に利用できるようになる

**デメリット**

* 計画立案時に全ての要件を作成する必要はないが、完成システムのイメージはステークホルダ間で共有されていなければならない
* ウォーターフォールモデルと比較すると、スケジュール/工程管理が複雑になる
* システムの分割が困難な場合がある
	* それぞれのサブシステムが高い独立性を持つ場合にしか利用できない
* 評価者の選定を慎重に行わなければならない

**どのようなプロジェクトに向いているか**

* 作りたいものの大凡のイメージはできており、しかし全体要件を定義出来るほど要求が明確でない場合
* システムをサブシステムに上手く分割できる場合(機能の独立性が高い場合)
* 期間的制約の弱いプロジェクト

-----

### インクリメンタルモデル

個人的な見解としては、ウォーターフォールの変化系モデルであると考えている。

**スパイラルモデルと同様に、システムを複数のサブシステムに分割し、サブシステム毎に開発していく**手法。

**スパイラルモデルと違い、全体の要求定義は先に完了させ、反復は行わない。**

ウォーターフォールモデルの工程を並行で走らせるイメージ。

![インクリメンタルモデル図](http://image.itmedia.co.jp/im/articles/0310/08/r5uml10_3.gif)

(引用元:http://www.itmedia.co.jp/im/articles/0310/08/news001.html)

**メリット**

* ユーザが機能を早期に利用できるようになる(スパイラルモデルと同様)
* スパイラルモデルやプロトタイプモデルと比較すると、工程管理が容易
* 要求定義が完了しているため、開発者の迷いを減らせる(ウォーターフォールモデルと同様)
* サブシステム毎の開発を行うため、ウォーターフォールモデルよりは手戻りコストが低い

**デメリット**

* 要求を予め定義しなければならないため、プロジェクト計画立案自体にコストがかかる(ウォーターフォールモデルと類似)
* 並行して開発を進行させていくため、開発内容が重複してしまう場合がある
* ウォーターフォールモデルと比較すると、スケジュール/工程管理が複雑になる(スパイラルモデルよりは容易)
* システムの分割が困難な場合がある(スパイラルモデルと同様)
	* それぞれのサブシステムが高い独立性を持つ場合にしか利用できない

**どのようなプロジェクトに向いているか**

* 要求/要件/目標が固定されており、途中変更のないプロジェクト(ウォーターフォールと同様)
* 予め全ての要求/要件/条件/期間/工程/責任を定義しなければならないプロジェクト(ウォーターフォールと同様)
	* 発注/受注案件など。
		* 何が出来ていれば成約か、特に相互の責任を明確にすべき場合
* **機能を随時リリースし利用していきたいプロジェクト**
* 期間的制約の強いプロジェクト

---

## 3. アジャイル開発

### 3-1. agileとは？

>  agileとは<br>
> 	(動きが)機敏な、はしっこい、(…に)機敏で、はしっこくて、頭の回転の早い、機敏な、明敏な

(引用元:https://ejje.weblio.jp/content/agile)


![アジャイル開発図](https://ec-orange.jp/ec-media/wp-content/uploads/2017/12/agile-development_01.jpg)

(引用元:https://ec-orange.jp/ec-media/?p=18702)

アジャイル開発をライフサイクルモデルと別項としたのには理由がある。

これまで紹介したライフサイクルモデルは、ソフトウェア工学の研究から生まれた、システム開発を効率的に進めるための経験則的ソフトウェアプロセスの集合、いわばフレームワークのようなものであった。これらはソフトウェアプロセスを定型化/評価し、いかに効率的な開発/保守を行っていくかという目的で考案されたと言える。

一方で、アジャイル開発という考え方はそれらとは少し違った見地から生まれたものである。

>プロセスやツールよりも個人と対話を、<br>
包括的なドキュメントよりも動くソフトウェアを、<br>
契約交渉よりも顧客との協調を、<br>
計画に従うことよりも変化への対応を、<br>
価値とする。すなわち、左記のことがらに価値があることを<br>
認めながらも、私たちは右記のことがらにより価値をおく。 

(引用元:[アジャイルソフトウェア開発宣言](http://agilemanifesto.org/iso/ja/manifesto.html))

>私たちは以下の原則に従う:<br>
価値のあるソフトウェアを早く継続的に提供します。<br>
要求の変更はたとえ開発の後期であっても歓迎します。<br>
動くソフトウェアを、2-3週間から2-3ヶ月という<br>
できるだけ短い時間間隔でリリースします。<br>
ビジネス側の人と開発者は、プロジェクトを通して<br>
日々一緒に働かなければなりません。<br>
動くソフトウェアこそが進捗の最も重要な尺度です。<br>
チームがもっと効率を高めることができるかを定期的に振り返り、<br>
それに基づいて自分たちのやり方を最適に調整します。<br>

(引用元(一部抜粋):[アジャイル宣言の背後にある原則](http://agilemanifesto.org/iso/ja/principles.html))

これまでソフトウェア工学で行われていたソフトウェアプロセスの定型化という研究とは逆に、ソフトウェアプロセスを柔軟かつ漸進的な非定型のものとして扱おうとしていることが読み取れる。

こうした思想が生まれた背景には、いくつかの理由が考えられる。

第一に、ソフトウェアプロセスの複雑化に伴う責任の明確化によって、副次的な成果物(要件定義書、仕様書、詳細設計書、テストエビデンス等)が増大し、「プロダクトを作る」という本質的な目的を達成するため道のりが遠くなってしまった側面があること。

第二に、webが発展したことによりソフトウェア開発に求められるものが変化したこと。ソフトウェアの利用される速度/頻度と改善要求の頻度は少なくとも相関、比例しているといってしまってもいい。少なくないソフトウェアが24h絶え間なく利用されるようになり、これまでの定型化されたプロセスを用いていては変化の速度に対応できない場合が出てきたのではないかと私は考えている。

第三に、ソフトウェア工学がある程度成熟してきたことで、基礎的な研究を応用できるタームに至ったのではないかと考えられる。前掲のアジャイルソフトウェア開発宣言の通り、アジャイル開発の理念は決してこれまでのソフトウェア工学で培われた経験則を否定/軽視するようなものではなく、それらの価値を認めた上でより現代にふさわしい価値を重視するというものである。既存のモデルを適宜最適な形で取り入れつつ、プロジェクトやチームによりふさわしい形の新しいモデルを追求していく、という姿勢こそがアジャイル開発の根幹であると言える。

以下に、約15年前、2003年時点での玉井による論を引用抜粋しておく。

> 開発/保守環境と運用環境の境界が喪失しつつあることにも，注目すべきであろう(中略)これまでのようにまず開発/保守環境でプログラムを作成し検証して，その後，運用環境へ移行するという段階を踏んだ作業は現実的でなくなってくる

引用元:[玉井(再再掲) 144頁](http://tamai-lab.ws.hosei.ac.jp/pub/sebook.pdf)


-----

### 3-2. アジャイル開発の手法

アジャイル開発と一言で言っても、スクラムやエクストリームプログラミング(XP)、リーンソフトウェア開発など様々な手法がある。

アジャイルの基本的な考え方は上述し、アジャイル開発に内包される様々な手法には細部の違いはあれ一定の共通した特徴がある。

そのため、ここではアジャイル開発手法の一つであるスクラムを紹介するに留める。


### 3-3. スクラム

Ken Schwaber/Jeff Sutherland両名によって開発されたアジャイル開発手法の一つ。

細かい手法やルールについては公式ガイドがあるのでそちらを参照の程。

参照:[スクラムガイド - 日本語訳](http://www.scrumguides.org/docs/scrumguide/v2017/2017-Scrum-Guide-Japanese.pdf)

![スクラム図](http://www.nec-solutioninnovators.co.jp/column/images/01_ScrumImage.png)

(引用元:http://www.nec-solutioninnovators.co.jp/column/01_agile.html)

スクラムの特徴は公式ガイドにあるように以下の三点が挙げられる。

* 軽量
* 理解が容易
* 習得は困難

私も実際の業務にこのスクラムを浅い知識のまま取り入れたことがある。その経験から言っても上記三点は納得できる内容である。特に二点目の"理解が容易"と三点目の"習得は困難"という点は注目すべき特徴である。開発手法の自体の理解は容易だが、理解をするのと実践するのとではまた違う。実践では数多くの問題が発生する。

公式ガイドにあるように、スクラムという開発手法は常にチーム構築/システム開発プロセスの改善を行っていく手法である。このことを軽視し、上辺だけスクラムを取り入れてしまうと私のように「なんちゃってスクラム」状態に苦しむことになる。実際、スクラムを取り入れ失敗するプロジェクトは数多く存在している。スクラム体制のコーチングのみで価値を認められるエンジニアも存在するほどに、スクラムの習得は困難である。

では、スクラムの実際の取り組み方を公式ガイドから抜粋し紹介する。

-----

### スクラムの理論

スクラムは、経験的プロセス制御の理論（経験主義）を基本にしている。

経験的プロセス制御の実現は、透明性・検査・適応の 3 本柱に支えられている。

* 透明性
	* プロセスの用語を参加者全員で共有している。
	* 作業する人とそのインクリメントを検査する人が「完成」の定義を共有している。
* 検査
	* スクラムのユーザーは、スクラムの作成物やスプリントゴールの進捗を頻繁に検査し、好ましくない変化を検知する。
* 適応
	* プロセスの不備が許容値を超え、成果となるプロダクトを受け入れられないと検査担当者が判断し
た場合は、プロセスやその構成要素を調整する必要がある。調整はできるだけ早く行い、これ以上の逸脱を防がなければいけない。

### スクラムチーム

スクラムチームは以下の三つの役割で成立する。

1. スクラムマスター
2. プロダクトオーナー
3. 開発チーム

![スクラムチームメンバ図](https://cdn-ak.f.st-hatena.com/images/fotolife/t/teeeeeeemo/20180221/20180221133413.jpg?1519187664)



**スクラムマスター**

* スクラムの促進と支援責務
	* 開発チームへの支援
	* プロダクトオーナーへの支援
	* 組織への支援
* 上記促進支援によるスクラムチームが創造する価値の最大化
* スクラムを成立させ続けるためのサーバントリーダー(奉仕/支援型リーダー)

**プロダクトオーナー**

* プロダクト価値の最大化責務
* プロダクトバックログの管理・透明化
	* プロダクトバックログ:プロダクトに必要だと把握しているものをすべて順番に並べた一覧
* 開発チームの作業価値最適化
* プロダクトバックログアイテムの周知

**開発チーム**

* 自己組織化責務
	* サブチームはない
	* 並列したプロフェッショナルであり上下関係はない
* スプリント毎のリリース責務



### スクラムイベント

スクラムは規則的なイベントを規定している。時間制限のあるイベントのみが存在でき、不要な時間的コストは削減されなければならない。

**スプリント**

スクラムのコアといっていい機能である。

* リリース判断可能なプロダクトインクリメントを作るための、1か月以下のタイムボックス(規定する)
* スプリントゴールに悪影響を及ぼすような変更を加えない。
* 品質目標を下げない。
* プロダクトオーナーのみがスプリントを中止できる。
	* とはいえ、スプリントを中止すべきことはほとんどない

**スプリントに内包されるイベントは以下の4つである**

1. スプリントプランニング
2. デイリースクラム
3. スプリントレビュー
4. スプリントレトロスペクティブ

**1.スプリントプランニング**

以下の問いに答えを出す会議である。先に挙げた三本柱の内、透明性の部分に関連の強い場。

* スプリントの成果であるインクリメントで何を届けることができるか？
* インクリメントを届けるために必要な作業をどのように成し遂げるか？

**2.デイリースクラム**

主に開発チーム作業計画をする場。日々の開発に関する検査、適応の機能を備える。

* デイリースクラムは毎日、同じ時間・場所で開催し、複雑にならないようにする。
* 開発チームは、次の 24 時間の作業を計画する。
* スクラムマスターは、開発チームにデイリースクラムを開催してもらう

**3.スプリントレビュー**

スプリント自体の検査の場。

注意：一部のみ抜粋している。

* スプリントの終了時にインクリメントの検査と、必要であればプロダクトバック
ログの適応を行うものである。
* 参加者は、スクラムチームとプロダクトオーナーが招待した重要なステークホルダーである。
* プロダクトオーナーは、プロダクトバックログアイテムの「完成」したものと「完成」していないも
のについて説明する。
* プロダクトオーナーは、現在のプロダクトバックログの状況を説明する。（必要であれば）現在
の進捗から、可能性のある目標とデリバリーの日程を予測する。
* 開発チームは、スプリントでうまくいったこと、直面した問題点、それをどのように解決したかを
議論する。
* 開発チームは、「完成」したものをデモして、インクリメントに対する質問に答える。「完成」の定
義にプロダクト機能のリリースが含まれていれば、それらを表示してレビューしてもらう。
* グループ全体で次に何をするべきかを議論し、次のスプリントプランニングに価値のあるイン
プットを提供できるようにする。
* 市場やプロダクトの利用状況によって、次に行うべき最も価値の高いことが変更される可能性
をレビューする。

**スプリントレトロスペクティブ**

スプリントに対する適応の場。

* スクラムチームの検査と次のスプリントの改善計画を作成する機会
である。
* スプリントレトロスペクティブは、スプリントレビューが終わって、次のスプリントプランニングが始まる前に行う。
* スクラムマスターは、このミーティングがポジティブで生産的になるようにする。
* 人・関係・プロセス・ツールの観点から今回のスプリントを検査する。
* うまくいった項目や今後の改善が必要な項目を特定・整理する。
* スクラムチームの作業の改善実施計画を作成する。


---

以上がスクラムという手法の規定である。

より詳細/正確な規定、実践的な内容については以下を参照。

* [スクラムガイド - 日本語訳](http://www.scrumguides.org/docs/scrumguide/v2017/2017-Scrum-Guide-Japanese.pdf)
* [Scrum基本のキ - 西村直人](https://www.slideshare.net/nawoto/summary-of-scrum-guide?ref=http://morizyun.github.io/blog/scrum-agile-xp-book-review/index.html)
* [スクラム概論 - Ryutaro "Ryuzee" YOSHIBA](https://www.slideshare.net/Ryuzee/scrum-8048905)
* [Agile-development-course-advanced - Miho Nagase](https://www.slideshare.net/MihoNagase/agile-developmentcourseadvanced12)

-----



一旦ここまで！！！！！！！