ソフトウェア開発手法を３行にまとめつつ勝手にカテゴライズ

いわゆる「ソフトウェア開発手法」と呼ばれるものには「～Ops」とか「～駆動～」みたいなのがいくつかあるのですが、名前は似ていてもそれぞれの手法がカバーしている粒度やジャンルが違かったり、あるいはこれはこれと近い話だがイコールではないとか対立するものではないみたいな説明があったりして、名前聞くたびに混乱するので、そのへん含めたいわゆる「開発手法」について自分なりにざっくりまとめてみました。

タイトルには3行とか書いていますが、改行が入るまでが1行ですってことで、見た目は大体3行に収まっていません。

# プロジェクト管理

## ウォーターフォールモデル
 * 開発工程（例：要求定義→設計→開発→テスト→導入→運用）を必ずや一方通行で進めようね、という手法。
 * ただ実は「後工程がうまくいかなかったときには、問題があった工程に一度戻ってね」という話も含まれているらしい。（が、それを正式に導入している現場は寡聞にして知らない。）
 * 工程の区切りがはっきりしているため、進行は一見遅いけれども、工程ごとの成果物がはっきりしていてチェックもしやすい（らしい）ため、工程ごとに仕事を切りやすいなどのメリットもある。ただ前工程の請負企業がやらかして後工程を請け負った別企業がうまく動けず結果システムができなくて裁判が泥沼化などのパターンも耳にする。（ウォーターフォールモデルそのものに恨みはありません）
 
## スパイラルモデル

 * 開発工程の、一部あるいは全部を繰り返すことで精度をあげていこうね、という手法。
 * 最近この名前自体をあまり聞かないが、開発手法としてはもはやこちらが主流。
 * アンチウォーターフォールモデルと思われやすいが、ウォーターフォールモデルの工程が短いスパンで繰り返すことをのならば、それはスパイラルモデルともいえる。なお、要求定義だけを先にやってあとの工程を繰り返し行う場合はウォーターフォールでもスパイラルでもなく反復型とかいうらしいが多分あまり厳密に分けられないんじゃないかな。

## プロトタイプ開発

 * 開発以前の段階でもドキュメントではなく実際に動くものを作ってみたほうがわかりあいやすいよね、という話。
 * 「プロトタイプ」の定義は、現場や状況により異なる。空気を読んでいこう。
 * これまでに見たことのあるプロトタイプのパターン：デザインをコードに起こしたもの、デザインは入ってないけど実装予定言語でのアーキテクチャがわかるもの、コア技術部分だけ実装されているもの、その他


# チーム管理

## アジャイル

* スパイラル・モデルをうまく実現するための、チーム管理も含めたベスト・プラクティス集。
* あるいはそれらの総称。「スクラム」「XP（エクストリーム・プログラミング）」などを総称して「アジャイル開発手法」とも言う。
* 「アジャイル」そのものが具体的な方法論の名称として提示される場合もあるが、その場合は、各手法からいいところをつまみ食いしろってことだな、と理解することにしている。

### スクラム

* アジャイル開発手法のひとつ。
* 泥臭くてもチーム一丸となってやっていこうぜ！みたいな感じ（個人の印象です）

### XP（エクストリーム・プログラミング）

* アジャイル開発手法のひとつ。
* チームメンバーそれぞれカッコよくやっていこうぜ！みたいな感じ（個人の印象です）

## 継続的インテグレーション（CI）

 * 品質改善や納期の短縮の達成のための対応を、継続的にやっていこうぜ！という話。
 * すなわち「自分たちの仕事に対する」業務改善（システム・インテグレーション）。
 * テスト自動化、ビルド自動化、コミット粒度を小さくすることは、CIそのものではなく、ベスト・プラクティスとされているもののひとつ。

## ChatOps

* CIとかで色々自動化したのはいいけど、通知が増えてメール増えすぎ。フィルターかけすぎて、みんなが騒いでる重要なエラー自分だけ見逃した件…
* あるいは、重大なエラーやら重要なインフォメーションやら、このメール気づいてますかーってchatから話しかけてはじめて反応するチームメンバーェ…
* だったらはじめからみんなが使ってるchatツールに情報流そうぜぇ！　って話

## テスト駆動開発

* 自動テスト用のテストコードを書いて、それに合格する実コード書こう！　そうすればテストの書き漏れなくなるよ！って話。これをテストファーストと言う。
* 定義にしたがえばテストコードをあとから作成する場合はテスト駆動開発ではないけれども、リリース時点でテストコードがそろっていることをテスト駆動開発を言っているところもあるので気にしない。
* CIやDevOpsの文脈で語られるのをよく見かけるが、実のところ「コードの開発着手時点ではっきりした設計がある」ことを前提とできるウォーターフォールモデルと相性が良い印象。

### ビヘイビア駆動開発

* テスト駆動開発から発展した、要はテスト駆動開発。
* 「テストって要は仕様だよね！　要件だよね！　もっと仕様や要件に沿ったテスト書いていこうぜ！　いや要件や仕様そのものをテストとして落とし込んでもいい！」って話
* テスト駆動開発の「テストファースト」に対して「スペックファースト」と言う。

# システム設計思想

## 多層アーキテクチャ

 * ソフトウェアアーキテクチャパターンのひとつ。大規模システムでは多かれ少なかれこれが前提となった設計が多い。プログラムをその役割ごとに整理して「層」にわけ、それぞれの「層」の各機能のインターフェースだけを定義して中の動きはブラックボックス化されているものとし「層」がお互いに連携しあって一つのシステムとして動くと考え設計する。層同士の呼び出しの可不可が定義されている場合もある。
 * オブジェクト指向プログラミングにおける「カプセル化」をシステム単位の設計でやっている感じ
 * 実装においては、層ごとに言語、実装方法、実装担当者などが異なる場合もある。異ならない場合もある。

### MVCモデル

 * 多層アーキテクチャのひとつ。かつて市場を席巻していたが名前そのものは最近あまり聞かなくなった。ただWEB系では、基本的な設計思想はここを基準として発展しているものが多い印象。
 * Model=データを抱えている層。View=表示を行う層。Controller=Model,Viewをつなぐ層。
 * ビジネスロジック（データや入力条件などによる条件分岐等の処理）をどの層に入れるのかということがいつも議論になる。

## オブジェクト指向分析設計

 * システムを設計、開発するにあたり、実世界（業務要件）との乖離が少なく、かつ楽であるといいよね。
 * 業務の１つの要素（概念モデル）がプログラムの１つのクラス（オブジェクト）と対応するとすれば、業務フローがそのままプログラムの設計として落としこめるんじゃね？　楽じゃね？　って話。
 * もちろん言うほど簡単にはいかないんだけどな！

## ドメイン駆動設計

 * システムを設計、開発するにあたり、実世界（業務要件）との乖離が少なく、かつ楽であるといいよね。
 * ほしいシステム設計するときどういうデータ設計するかーとかよりも要は要求の業務（ドメイン）をそのままプログラムに落としこめばいいんだろ？　そのままやれば簡単じゃん！　なんでずれるの？　ああ、業務知ってるやつ（ドメインエキスパート）と技術持ってるやつってたいてい別だからそこのコミュニケーションがうまくいかないんだ？　じゃあユビキタス言語っていう共通言語作ってそこで定義された言葉でやりとりしようぜ！　って話。
 * もちろん言うほど簡単にはいかないんだけどな！

## オブジェクト指向プログラミング

 * オブジェクト指向設計とオブジェクト指向プログラミングは別物だから！　設計はグダグダでもプログラミングはオブジェクト指向にしよう、な！
 * 要は、同じようなところに属しているものはひとつのクラスに閉じ込めてわかりやすく、管理しやすくしようって話。
 * 「同じプレフィックスを持つ関数、変数」の多発は「ク・ラ・ス・化」のサイン。


# さいごに

「システム設計」という一言のなかに、機能デザイン（要望からのプログラムへの落とし込み）、アーキテクチャ設計、個別のコードの良い書き方的な話、を全部ごっちゃにしてしまったので、我ながら途中からよくわからなくなりました。ごめんなさい。