書籍『XPエクストリーム・プログラミング入門 変化を受け入れる』のまとめ

## 所感
非常に抽象的な概念が書かれている本なので、咀嚼するまでに時間がかかりました・・・。
XPというとなんとなく「ペアプロ」「TDD」を連想するのですが、本書を通じてそれらのプラクティスはあくまで5つの価値を生み出すための手段でしかないということに気づくことができました。まず「価値」があり、価値を生み出すための抽象的な考え方である「原則」があり、さらに価値を生み出すための具体的な手段である「プラクティス」があるという構造だと認識しました。
あとはXPの原則である「人間性」や「多様性」など、人に注目した話がよく出てくるのが印象的でした。他者を尊重しつつ自分の意見を率直に言うことは難しいのですが、5つの価値に結びつく大事なファクターなのではないかと感じました。

なお、15~22章は読み物としての側面が強い（体系的にまとめづらい）と感じたため、割愛させていただいています。

## まとめ
### XPとは
- XPは以下のことに焦点を当てたソフトウェア開発手法のことである
    - プログラミング技術
    - 明確なコミュニケーション
    - チームワーク
-　XPチームは成功のために全力を尽くし、結果の責任を受け入れる
    - 人に管理されるのではなく、自分で全力を尽くし、正直に伝えること
- XPは運転に似ている
    - 運転では常に注意を払い、ハンドルをこっちに少し、あっちに少しと修正する
    - XPでは頻繁に小さな修正をデプロイして、目標に向かって前進する

### 価値
- ある状況で何が望ましく、何が望ましくないかの根拠
    - 端的に言えば、「重要なこと」
    - 直感・経験を元にした基準
- チームが焦点を当てるべきな重要なこと

#### コミュニケーション
- 開発中に起きる問題のほとんどは、他の誰かが知っている
- 問題が起きた場合は、それがコミュニケーションの欠如によって発生したのかを自問自答するべき

#### シンプルさ
- 「動作させるために最もシンプルなことは何か？」
    - 不要な要件・今日の時点で組み込む必要のない要件を省く
- 何がシンプルかは状況によって異なる
    - 2台のマシンにシステムを分割せざるを得ない場合は、複雑であってもそれがシンプルだと言える
- コミュニケーションと互いにサポートし合う
    - コミュニケーションを改善すると、無駄な要件を減らすことができる
    - シンプルにすることを実現すれば必要なコミュニケーションは少なくて済む

#### フィードバック
- 変更が多いシステム開発において「最初から完全」はありえない。フィードバックを使って目標に近づくようにする。
- XPチームはなるべく多くのフィードバックを得ることを目指す。
- フィードバックはシンプルさに貢献する
    - 3つの解決策のうちどれがシンプルか？全部試して確認する

#### 勇気
- ソフトウェア開発にまつわる恐怖に対処することで、効率的に作業ができる
- 他の価値と合わせることで協力になる
    - 真実を伝える勇気によってコミュニケーションと信頼が深まる
    - 失敗を捨て去り、新しい解決策を探す勇気によってシンプルにすることが促進される
    - 解答を探す勇気によってフィードバックが得られる

#### 尊重
- これまでの4つの価値の背後にある（前提である）価値
- チームメンバが互いに無関心な状態では、XPは機能しない。

### 原則
- どう振る舞うかの指針
    - ドキュメントと会話、どちらが優先されるかはすべての条件が同じであれば、原則会話とされる
- 価値とプラクティスを結びつける
    - 価値は普遍的だが、プラクティスは状況によって変わる

#### 人間性
- ビジネスだけでなく、開発者個人の要求も満たされるようにする
    - 身体的危害や失業の不安がない
    - 開発者が社会に貢献する機会がある
    - 会社に属していることを実感でき、評価と責任を受けられる
    - 開発者としての技術を発展する機会がある
    - 他人を理解し、他人から理解される

#### 経済性
- 行っていることにビジネス価値があるようにする
    - 「技術的な成功」は虚しい勝利

#### 相互利益
- すべての活動が、関係者全員の利益になるようにする
- 「膨大なドキュメント」はこの原則に反するプラクティスである
    - 将来関与する人には利益だが、開発速度を落とすため現在の関係者には不利益になる
        - 「自動テスト」「リファクタリング」「一貫性がある命名」などは、将来関与する人と相互有益な方法である

#### 自己相似性
- ある解決策を、別の状況でも使ってみる
    - 「失敗するテストを作成し、そのテストを動作させる」というTDDのリズムを他の状況にも当てはめる
        - 四半期単位では、取り組みたいテーマを一覧にして、ストーリーを出してテーマを網羅する
        - 週単位では、取り組みたいストーリーを一覧にして、これらのストーリーを表現するテストを作成・動作させる
        - 数時間単位では、作成する必要のあるテストを一覧にして、テストを作成・動作させ、一覧が終了するまで繰り返す
- ある解決策が別の状況で機能するとは限らないが、よい出発点にはなる
- 参考: [フラクタル](https://ja.wikipedia.org/wiki/%E3%83%95%E3%83%A9%E3%82%AF%E3%82%BF%E3%83%AB)

#### 多様性
- チームは様々なスキル・姿勢・物事の見方を結集して、問題に取り組む
- 多様性に衝突は付き物
    - 衝突は「機会」であり、プログラマ両方の意見を重視すべきである
    - 他人を敬い、自分自身を維持することが大事

#### 反省
- 作業を行う際には、作業方法と作業理由も考える
    - 成功した理由や失敗した理由を分析することができる
- 四半期やイテレーションごとにとらわれず、会話や読書といった普段の活動からも反省することができる。

#### フロー
- 開発のすべての活動（コーディング・自動テスト・ビルド・デプロイ…）を個別のフェーズではなく、連続的な活動として行う
    - 1度に多くの価値を提供しようとしない

#### 機会
- 問題が起きた際には、「変更の機会」だと考える
    - 「存続させる」ではなく、「向上させる」
    - 各問題を機会へと意識的に変換することがエクストリームであることに含まれる

#### 冗長性
- 　冗長性をもたせることで最悪の事態を避けるようにする
- 　XPでは、バグに対して冗長性のあるプラクティスで対処する
    - 　ペアプログラミングで、パートナーがバグを見つけてくれる
    - 　全員同席で、誰かが欠陥を見つけてくれる
    
#### 失敗
- 　成功が難しい場合には、失敗してみる
    - 　3つの方法のうちどれが正しいかわからない場合は3つすべての方法を試す
- 　知識を与える失敗は無駄ではない

#### 品質
- 　品質を決して犠牲にしない
    - 　品質を下げてもプロジェクトは早く進まず、むしろ遅延する
    - 　品質を向上させると納品も早くなる
    - 　経済的要因以外でも、「人は誇りに思える仕事をすべきである」という観点からも品質を犠牲にしてはいけない。
- 　プロジェクト管理には品質の代わりにスコープを使う

#### 小さなステップ
- 　重要な変更を1度に行わない
- 　小さなステップでは、失敗を捨てるときのオーバーヘッドが少ない

#### 責任の受け入れ
- 　責任は割り当てるものではなく、受け入れるものである
    - 　責任があるかどうかを判断できるのは、当のプラグラマだけ

### プラクティス
- プラクティスはXPチームが日々行うこと
    - 価値によって目的が与えられて、初めて意味を持つ
- 価値を元に行う行動
    - コミュニケーションを重視している（価値）から、デイリースタンドアップミーティングに出席する（プラクティス）

#### 基礎プラクティス

##### 全員同席
- チーム全体が入れるだけの十分な広さの空間を確保すること
- プライバシーを満たすために小さなプライベート空間を作ったり、労働時間を制限する

##### チーム全体
- プロジェクトの成功に必要なすべてのスキルを持つ人々からチームを構成する
- 部門を超えた「職能横断的チーム」という考えと同じ

##### 情報豊富な作業空間
- 自分の作業空間を、行っている作業が明確にわかる空間にする
- 利害関係者が作業空間に入って15病でプロジェクトの見通しを把握できる状態
- 壁にグラフやストーリーカードを分類して貼ることで情報を迅速に伝えることができる

##### 活気のある仕事
- 高い生産性を維持できる時間で仕事を行う
- 病気のときに仕事に来るのは、仕事への貢献を示すようにはならない

##### ペアプログラミング
- 1台のマシンの前に2人で座った状態ですべてのプログラムを作成する
    - 2人で会話しながら、同時にプログラミングを行ってプログラムを向上させようとすること
- ペアプログラマが行う内容
    - 互いに職務に集中する
    - システムを洗練することについて意見を出し合う
    - アイデアを明確にする
    - パートナーが作業に行き詰まったときにはイニシアチブを取る。
    - チームのプラクティスに対する責任を互いに負う

##### ペアプログラミングと個人の空間
- ペアを組む両者が居心地がいいパーソナルスペースを設定する
- ペアを組む際は個人の衛生と健康を考える
    - 咳をするときには口を抑える、匂いの強い香水はつけない・・・など

##### ストーリー
- 顧客の目に見える機能単位で計画する
- ストーリーとその他の要件処理方法との違いは「早期の見積もり」である
    - 見積もりはビジネス観点と技術的観点の交換の機会になる
    - 実用性の高いアイデアを早期に生み出すことができる
    - 最小の投資から最大の利益を得る方法について考える
    
##### １週間サイクル
- 1週間単位で作業を計画する
- 週の頭にミーティングを行う
    1. 現在までの進捗状況のレビュー前（週の予測と実際の進捗を見比べるなど）
    1. 今週実装する1週間分のストーリーを顧客に選択させる
    1. ストーリーをタスクに分割する
- 週の始まりはストーリーの完了時に成功する自動テストを書き、残りの日にちでテストがパスすることを目指す

##### 四半期サイクル
- 四半期単位で作業を軽各区する
- チーム・プロジェクト・進捗・大きな目標との調整を考える
    - 四半期ごとのテーマを計画する
    - テーマに対応する四半期分のストーリーを選択する
    - チーム外で管理されているボトルネックを特定し、修正する
    - 全体像に焦点をあてて、プロジェクトが組織に適合しているかを確認する
- 「テーマ」は市場戦略のロードマップ
- 「ストーリー」は全体像をあまり考えず、今週集中する作業

##### ゆとり
- 計画には、遅れが生じた場合に捨てることができる重要でないタスクを含めること
    - ex) 8週のうち1週は「マニアの週」にする
    - ex) 1週間分の予算の20%はプログラマが選択したタスクに当てることにする

##### 10分ビルド
- 10分間でシステム全体を自動的にビルドし、すべてのテストを実行する
    - 10分以上かかると実行されることが少なくなり、フィードバックの機会を失う
- まずは「ビルドしてテスト実行」といった一連のプロセスの自動化を目指す

##### 常時結合
- 2, 3時間以内に変更の結合とテストを行う
    - チームで行うプログラミングは分割統治ではなく、「分割し、統治し、結合する」ことである
- 常時結合には非同期式と同期式がある
    - 非同期式は、変更をチェックインするとビルドシステムが変更を検知し、ビルドとテストを実行する
        - 問題があればメールなどで通知される
    - 同期式は変更をチェックインしたあとすべてのテストスイートが実行されるのを待つ
        - 待っている間に自然な反省時間が生まれる
        - 手戻りがない

##### テストファーストプログラミング
- コードを変更する前に、失敗する自動テストを作成する
- テストファーストプログラミングは多くの問題を解決する
    - 仕様の拡大
        - 「万が一に備えて」コードを挿入することを防ぐ
        - 本当に必要な場合は現在の作業を行ったあとで別のテストを作成する
    - 結合度と凝集度
        - テストの作成が困難な場合は、結合度が高く、凝集度が低い設計ミスの表れ
    - 信頼
        - 動作するきれいなコードを作成し、自動テストによって意図を示すことで仲間から信頼を得られる
    - リズム
        - 次に行うべきことが明確になる
        - 「テスト→コード→リファクタリング、テスト→コード、リファクタリング…」
- 静的分析やモデルチェックといったツールをテストファースト方式で使用できるかもしれない
    - システムにデッドロックがないかを「テスト」する
    - すべての変更が終了したら、再度デッドロックがないことを検証する
- ソースコードの変更のたびにテストが実行される「常時テスト」方式もある

##### インクリメンタル設計
- システムの設計に毎日投資する
- システムの設計をその日のシステムの必要性に適合させるように努める
- XPチームは将来の要件に設計を適合させる
    - ソフトウェアの変更による費用が劇的に増えない状況にする
    - 小さくて安全なステップで設計を変更する

#### 応用プラクティス

##### 実顧客の参加
- システムによって生活やビジネスに影響を受ける人をチームの一員にする
    - 顧客は自由に使える予算があり、開発リソースを何に費やすかを選ぶことができる
- 「ある人に特化したシステム」になるという反論があるが、成功したシステムを一般化する方がゼロから作るより容易である

##### インクリメンタル配置
- 既存のシステムをリプレイスする際に、プロジェクトの最初から移行作業を順次行っていく
    - 一気に大規模なリプレイスをしない

##### チームの継続
- チームメンバの交代は適度な頻度にする
    - チームが安定したまま、知識と経験の継続的な拡大というメリットが得られる

##### チームの縮小
- チームの能力が向上したら作業量を一定に保ったまま、徐々にチームの人数を減らす
- 余った人同士で別のチームを形成できる

##### 根本原因の分析
- バグが見つかるたびに、バグと原因を取り除く
    - バグの再発防止とチームが２度と同じ間違いをしないようにするため
- バグに対処するためのプロセス
    - バグを実証するため、要求される振る舞いを記述したシステムレベルの自動テストを作成する
    - 最も小さいスコープでユニットテストを作成し、バグを再現させる
    - ユニットテストが動作するようにシステムを修正し、システムレベルのテストも動作することを確認する
    - バグが生じた理由と見つけられなかった理由を考える
        - [5回のなぜ](https://www.google.com/search?q=5%E5%9B%9E%E3%81%AE%E3%81%AA%E3%81%9C&rlz=1C5CHFA_enJP945JP945&oq=5%E5%9B%9E%E3%81%AE%E3%81%AA%E3%81%9C&aqs=chrome..69i57j0i512l3j0i30j0i5i30.7756j0j7&sourceid=chrome&ie=UTF-8)で考える

##### コードの共有
- チームメンバ誰でもシステムのあらゆる部分を常に改善することができる
- コードの各部分に対して責任者をおかない

##### コードとテスト
- 永続的な成果物としてコードとテストだけを保持する
    - コードとテストからドキュメントを生成する
- 直接的な価値を生み出すコードとテスト以外の成果物はすべて無駄である

##### 単一のコードベース
- 単一のコードだけを存在させる
- コード分岐は無駄を作り出す
    - 現在デプロイされているシステムのバグを修正すると、ほか全てのシステム、ブランチに修正を取り込まなければいけなくなる
    - 取引先によってソースコードのバリエーションを変えない

##### 日時配置
- 毎晩、新しいソフトウェアを本番環境に配置する
- 日時配置には複数の必須条件がある
    - プログラマが作成している内容と本番環境の内容にずれがない
    - 1年あたりの欠陥が数件以内である
    - 　ビルド環境が自動化されている
    - 　デプロイツールがインクリメンタルなロールアウトとロールバックを含め自動化されている
    - 　チームと顧客の間に強い信頼が築かれている

##### 　協議によるスコープ契約
- 　ソフトウェア開発に関する契約を作成する
    - 　時間・費用・品質を定め、開発スコープを継続的に協議することを要求する

##### 　利用分払い
- 　課金体系を「システムが使用された分だけユーザに課金する」利用分払いシステムにする
- 　お金は究極のフィードバック
    - 　何に対して改善を促進するかについて、正確な情報を適宜得ることができる
- 　リリース分払いでは、サプライヤーの利益と顧客の利益が対立する
    - 　サプライヤーは多くの中身のないリリースを行おうとする
    - 　顧客は各リリースに多くの機能が含まれることを望む
- 　サブスクリプションモデルでも、継続率でフィードバックを得ることができる

### XPチーム全体
- プロジェクトにおけるメンバの役割
    - 1人に1つの役割を割り当てるということではない
    - プログラマがアーキテクトの役割を果たすかもしれない

#### テスター
- 顧客が導入前にシステムレベルの自動テストの選択と作成を行うのを手伝う
- プログラマにテスト技術を指導する

#### インタラクション設計者
- システムの全体的なメタファを選択し、ストーリーを作成し、デプロイされたシステムの使い方を検討する
    - 簡潔に言うと、システムの行うべきことを考える
- 顧客とともに作業し、ストーリーの作成と明確化を支援する

#### アーキテクト
- 大規模なリファクタリングの調査と実行、アーキテクチャに負荷をかけるシステムレベルテストの作成、ストーリーの実装を行う
- プロジェクトのアーキテクチャを、プロジェクトが進むにつれて方向付ける
- システムの自然な境界線を見つけ、独立した部分ごとにシステムを分割する
- 総じて、全体像を把握しながらシステム全体に目を向ける役割を負う

#### プロジェクトマネージャ
- チーム内のコミュニケーションを促進し、顧客、サプライヤー、他の組織とのコミュニケーションを調整する
- プロジェクトの情報をステークホルダに正確に提示できるようにする
- 計画と現実の同期をとるため、計画プロセス自体を改善する

#### プロダクトマネージャ
- ストーリーを作成し、四半期サイクルのテーマとストーリーを選び、1週間サイクルのストーリーを選び、実装時にストーリーの曖昧な部分について質問に答える
- ビジネス上の理由によってストーリーに優先順序付けをする
- 顧客とプログラマ間のコミュニケーションを奨励する

#### 重役
- XPチームに勇気、自信、責任意識を与える
- 大規模な目標を明確化し、チームと企業の目標を一致させる
- チームが優れたソフトウェアを作成しているだけでなく、継続して改善していることも確認する
- チームに対してXPプロジェクトに関するあらゆる質問をでき、納得しなければチームに反省を求めて再度説明を求める
- 意思決定に必要な情報をチームから聞くことができる

#### テクニカルライター
- 機能についてのフィードバックを早期に提供し、ユーザーとの密接な関係を築く
    - 追加機能を最初に目にする役割
        - テクニカルライターへの説明という行為が早期のフィードバックになる
    - ユーザが製品について学習するのを支援し、フィードバックを聞き、資料やストーリーを追加する

#### ユーザ
- ストーリーの作成と選択を行い、開発時には専門的な決定を行う
- ユーザが構築しているシステムと同じようなシステムについての広い知識と経験を持っている場合や、システムを利用するユーザコミュニティと密接な関係を持つ場合に重要な役割となる

#### プログラマ
- ストーリーとタスクを見積もり、ストーリーをタスクに分割する
- テストを作成し、機能を実装するためのコードを作成する
- 退屈な開発プロセスを自動化する
- システムの設計を徐々に改善する
- ペアを組んで本番コードを作成するため、社会的スキルと人間関係のスキルを高める必要がある

#### 人事
- 評価と雇用をする
- XPではチームの業績を重視して評価を行う
- XPにおいて有能な従業員
    - 礼儀正しく振る舞う
    - チームワークを乱さない
    - イニシアチブを取る
    - 責任を果たす
- XPチームは、チームワークと社会的スキルを非常に重視して雇用を行う
    - 最良の面接方法は応募者に1日ペアプログラミングでチームと一緒に作業させること

### 制約理論
- どんなシステムでも1度に1つ以上の制約（ボトルネック）が存在するという理論
    - ある制約を取り除くと、別の制約が作られる
- システムの処理能力を向上するためには制約を見つけ、改善する
- 局所的な最適化ではなく、全体的な処理能力を重視する

### 計画： スコープの管理
- XPでの計画は、現在の目標、過程、事実をすべて検討することから始まる
    - 何がスコープ内で、何がスコープ外なのか、次にやるべきことの合意を取る
- 計画は浮上した事実に合わせて変更することができる
- 時間と費用は動かせないので、スコープを動かしてプロジェクトの進捗を制御する
    - 品質を落としても作業量が減ることはない

### テスト： 早期、頻繁、自動化
- バグはソフトウェアの信頼を破壊してしまう
- XPのプラクティスでは、最初からバグが発生しないために明確なコミュニケーションを目指す
    - バグが発生した場合は、将来同じ問題を起きないように対処する
- バグの削減への投資は、チームワークへの投資でもある
    - 1人のメンバがミスをするたび、他のメンバーの時間・労力・信頼への負担になる
    - 自分の身を守るためにエラーを隠すことは、時間と労力の無駄である
- DCI(Defect Cost Increase: 欠陥費用増加)
    - 欠陥を見つけるのが早いほど、欠陥の修正も安価になる
    - 頻繁なテストによって、費用と欠陥を削減できる
- ダブルチェックの効果を最大化するために、プログラマ視点と顧客視点の2つのテストを書いてバグを修正する

### 設計: 時間価値
- インクリメンタル設計は、機能の提供を早く、かつ毎週継続的に行うための方法
    - 設計が日常業務の一つになっていれば、プロジェクトがより円滑に進められるだろうという提案
- BDUF(Big Design Up Front: 事前の大規模設計)をせず、LDUF(Little Design Up Front: 事前の小規模設計)、またはEDUF(Enough Design Up Front: 事前の十分な設計)を行う
    - 事前設計は初期の実装を行える程度で十分
    - それ以上の設計は、実装が終わって設計に対する実際の制約が明白になってから行う
- データベースのインクリメンタル設計の戦略
    - 空のデータベースから始める
    - 自動化されたスクリプトを用いてすべてのテーブルと列を追加し、必要に応じて既存のデータを移動させる
    - スクリプトを実行してどの段階のデータベースでも、後の段階のデータベースにアップデートできるようにスクリプトに連番を付ける（現代のフレームワークが提供する、いわゆるマイグレーション機能）
- Once and Only Once(絶対一度だけ)設計
    - データ、構造、ロジックの重複を見つけるたびに設計に投資する
- コードを修正しながら、少しずつ整理する
- 横道にそれて設計の改善だけを行わない
- 今日影響のある設計だけを行う
- XP流の設計を採用すると、設計決定のタイミングを遅らせることができる
    - 経験を踏まえて、即座に決定できる時が来るまで設計を遅らせる
- 設計のシンプルさの4つの評価基準
    - 対象となる顧客に適合している
        - 設計が見事であることは重要でなく、それを使用して作業する必要のある人が理解できることが重要
    - 伝達性
        - 伝える必要のある各アイデアがシステムで表現されている
        - システムの要素は将来の読者に意図を伝える必要がある（[叫ぶアーキテクチャ](https://yotiky.hatenablog.com/entry/CleanArchitecture05#%E7%AC%AC21%E7%AB%A0-%E5%8F%AB%E3%81%B6%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3)）
    - 分解済み
        - ロジックや構造の重複は、コードの理解と修正を困難にする
    - 最小限
        - 上記３つの制約内で、システムの要素はできる限り少なくすべき
        - 要素が少ないというのは、テスト・ドキュメント・伝達が少なくなることを意味する