「エンジニアリング組織論への招待」要約と感想

今さらながら [エンジニアリング組織論への招待](https://amzn.to/2YXeWXa) を読んだので要約と感想をメモ。

# 総論(たぶん)
エンジニアリングに関わる問題の多くは、組織の問題と密接に関連しているので、その解決にあたっては組織というものを正しく理解する必要がある。

# Chapter 1 思考のリファクタリング
エンジニアリングの本質は「不確実性の削減」にある。
不確実性には「環境不確実性」と「通信不確実性」があり、環境不確実性とは「未来のことは分からない」、通信不確実性とは「他人のことは分からない」ということ。

不確実性を下げるには、情報を生み出す必要がある。

その際に重要なのが、以下の3点。

* 論理的思考の盲点を知ること
* 経験主義と仮説思考
* システム思考

## 論理的思考の盲点
論理的思考とは、事実を正しく認知し、そこから正しく演繹すること。
ところがそれは意外と難しい。
その難しさがどこにあるのかを理解することで、非論理的な思考に陥ることを防ぐことが重要だ。

事実と意見は混同されやすいし、判断は感情の影響を受けやすい。

中でも怒りの感情は影響が大きいので、適切にコントロールする必要がある。
怒りをそのまま伝えると攻撃の応酬となり、より大きなトラブルに発展しがちなので、自身の「悲しみ」として表現するとよい。

## 経験主義と仮説思考
経験主義とは実験・行動することによって不確実性を減らす考え方。
つまり「未来のことは分からない」ので、行動することで未来を現在にする。
これは具体的な事象の観察から結論を導き出すという意味で、帰納法的である。
スクラムは経験主義に基づいている。

経験主義の対極は理性主義で、理性的に考えれば正しい結論に到れるという考え方。
ウォーターフォール型開発プロセスは理性主義を前提にしていると言える。

経験主義で重要なのは、行動によって新たな知識を獲得すること。
そのためにはコントロールできるものとできないものを区別し、コントロールできるものを操作すると同時に、その結果を観測する必要がある。

仮説思考とは、演繹的(理性主義)でもなく、帰納的(経験主義)でもない考え方。
少ない情報で大胆な仮説を立て、それを検証していくアプローチ。
つまり、必ずしも事実・データに立脚しない。
仮説思考では、何をどのように検証するのかが重要となる。

仮説思考をうまく利用すると、意思決定を遅延することができる(リアルオプション戦略)。
つまり、まずは小さな投資で仮説の検証を行い、その結果を元に最終的な判断を行うことで、期待値を最大化する。
プロダクト開発におけるMVP (Minimum Viable Product) はその具体例である。

いずれにせよ不確実性に対処するには、「行動を通じて新たな情報を生み出す」という、経験主義と仮説思考に共通する考え方が重要となる。

## システム思考
要素と全体の関係性において、要素ひとつひとつの性質を細かに理解することで全体も理解できるという考え方を「要素還元主義」と呼ぶ。

一方で、現実には要素同士はネットワーク構造を持ち、非線形な関係性に基づく相互作用により、個別の要素の性質の総和からは全体の性質を導き出せないことも多く、そのような要素の集まりのことを「システム」と呼ぶ。
その前提に立ち、要素間の関係性に注目して全体の特性・振る舞いを明らかにしようとする考え方が「システム思考」である。

システムの内部には「フィードバックサイクル」が発生する。
フィードバックのタイプには拡張と抑制があるが、ビジネスにとって良い結果をもたらす拡張のフィードバックサイクルを見つけ出し、加速させることが重要である。

不確実性を減らすための情報を生み出すという点では、システムや問題の全体像を把握できるようになることが重要で、そのためには「視野を広く」「視座を高く」「視点を鋭く」持つ必要がある。

# Chapter 2 メンタリングの技術
自分にとって特に新しい内容ではなかったのでスキップ。

# Chapter 3 アジャイルなチームの原理
「アジャイル開発」とは、チームの生産性を向上させるための方法論で、Chapter 1と2で解説された考え方が基盤となっている。

アジャイル開発が必要とされる理由のひとつは「ソフトウェアの大規模化と複雑化」。
製造業をモデルとした従来型の開発プロセスが通用しなくなってきた。

もうひとつは、「マーケットの不確実性に対応する必要性」が増してきたこと。
ソフトウェアの利用者が政府や大企業から一般の人々になってきたことで、ニーズを把握する難易度が上がるだけでなく、ニーズが変動するスピードが速まった。

調査によるとアジャイル開発の成功率は従来型に比べて3倍で、失敗率は3分の1、大規模開発においてはより効果的である。

また、マーケットの不確実性の増大は「プロジェクト型開発」から「プロダクト型開発」への移行を促す。

プロジェクトは有期限であり「終えること」が重要なので、「スケジュール不安」の発生源である「方法不確実性」(どのように作るか)に対処することになる。

逆にプロダクトは「終わらないこと」による継続的な収益が重要であり、マーケットに受け入れられるかどうかという「マーケット不安」の発生源である「目的不確実性」(何を作るか)に対処する。

方法不確実性も目的不確実性も、どちらも環境不確実性(未来のことは分からない)の一種であるが、従来型のウォーターフォール開発では、最初に要件定義で目的不確実性を減少させ、その後の設計・見積りで方法不確実性を減少させる。
しかしこのアプローチは理性主義的であり、実際に不確実性を減少できる可能性は低い。

対してアジャイル開発では両方の不確実性に少しずつ対処する。
小さなリリースを重ね、そこから得られるフィードバックを元に計画を修正するので、経験主義的と言える。

# Chapter 4 学習するチームと不確実性マネジメント
## スケジュール不安と方法不確実性への対処
目的の機能・プロダクトが「いつリリースされるのか」という問いになるべく早期に答えるために行うのがスケジュールマネジメントで、3つの要素から成る。

* 個別タスクの見積り
* 制約スラック
* プロジェクトバッファ

制約スラックとはタスク同士の依存関係に起因する無駄のこと。
属人化したタスクがあると、特定の人の生産性が全体のボトルネックになる(リソース制約)。
タスク間に前後関係があると、それらのタスクを並行処理することができない(依存制約)。
属人性を減らし、作業を分解して並行実施できるようにすることで、制約スラックを減らすことができる。

プロジェクトバッファは見積りの不確実性を吸収するために設ける時間的余裕。
バッファはタスクごとに設けるのではなく、プロジェクト全体で設ける。

不確実性を吸収するのに十分なバッファが残っているかどうかは、プロジェクト全体の「不安量」から判断する。
不安量は各タスクの多点見積りから算出する。

不安量が大きいタスクから先に着手すること。
これによりスケジュール後半になってリスクの大きなタスクが残っている状況を避けることができる。
また、不安量の大きなタスクを分解し、不安量を小さくすることも重要。

そもそもタスクに要する時間を見積もることは難しい。
相対見積りを行い、小さなスプリントをいくつか実施してベロシティを計測すると、実績ベースでバッファの過不足を判断できるようになる。

## マーケット不安と目的不確実性への対処
スケジュール不安には「プロジェクトバッファ」で対処するのに対し、マーケット不安には「スコープバッファ」で対処する。

「当初計画していた機能群」と「最低限の価値検証が可能な機能群」(MVP = Minimum Viable Product) との差がスコープバッファで、予定していた機能のすべてが完成しない場合にはMVPを下回らない範囲で一部の機能を削ってリリースできるようにする。

リリース可能な時点のことを「リリースポイント」と呼ぶが、スコープバッファを機能させるにはリリースポイントをこまめに作る必要がある。
「ユーザーストーリー」単位で開発を進めると、各ユーザーストーリーの開発が完了する都度、リリースポイントを設けることができる。
その際には「INVEST」の基準に従うと、ユーザーストーリーを適切な粒度に保ちやすい。

マーケット不安を解消するには仮説検証を実施するが、不確実性の大きなものから小さなコストで検証していく。
また、良い仮説を立てるのに有用なツールが「リーンキャンバス」である。

## スクラム
スクラムというアジャイル開発フレームワークは、3種類の不確実性に対処するための方法論である。

* 環境不確実性(未来のことは分からない)
    * 方法不確実性(どのように作るか)
    * 目的不確実性(何を作るか)
* 通信不確実性(他人のことは分からない)


# Chapter 5 技術組織の力学とアーキテクチャ
## 生産性とコミュニケーション
労働生産性は一般的には「従業員一人あたりの付加価値額」とされるが、これをエンジニア組織にそのまま当てはめることはできない。
なぜならソフトウェアは一度作ると、コピーやユーザー追加が容易にできるので、労働生産性は開発中は低く、完成後に投資をやめると高くなるから。

エンジニアリングの本質は不確実性の削減 ＝ 情報を生み出すことであるなら、情報処理能力の高さを生産性の高さとみなすのが適当そうである。

つまり、エンジニアリング組織の生産性を向上させるには、組織全体のコミュニケーションを改善する必要がある。

## 権限委譲
組織のコミュニケーション効率を向上させるには、権限の委譲が重要となる。
より少ない指示、より抽象的な指示で動ける組織は情報処理能力が高いと言えるが、それも権限の委譲により実現される。

ただし権限と責任は一致していないと、逆に組織の情報処理能力は低下する。

また、権限は「会社の資産やリソースに対する自由度」と考えられるが、複数の人物が同一のリソースに対する権限を持つ場合に「権限の衝突」が発生しうる。

衝突の解決にはコストがかかるので、衝突が発生しにくく、発生した衝突の解決がしやすい組織構造とすることが重要である。

## 技術的負債
技術的負債とはソフトウェア開発の段階が進むにつれ、機能追加が徐々に困難になっていく現象のことである。

技術的負債には「外からは見えない」という特徴がある。そのため「負債の返済」の重要性は非エンジニアには理解されづらい。

クラウス・シュミットは数式を用いてこれを可視化しようとした。
技術的負債のある現実のシステムに対し、リファクタリングされた(技術的負債が返済された)「理想のシステム」を想定すると、それぞれに対してある機能を追加する際の工数の差を技術的負債と考えることができる。

これにより技術的負債の返済が割に合うかどうかを、非エンジニアも議論できるようになる。

一方で、機能やバグのような「外から見える」ものについて、エンジニアと非エンジニアが共通認識を持っているかというと、そうとは限らない。経営者やプロダクトオーナーが考えているプロダクトの未来はエンジニアに十分共有されていないかもしれない。
そしてこのことは負債を返済すべきかどうかの判断に影響する。

結局のところ技術的負債をめぐる問題というのは、エンジニアと非エンジニアの間の情報の非対称性に起因しており、つまりこれもまたコミュニケーションの問題なのである。
このような情報の非対称性の解消するには次のような方法がある。

* アーキテクチャーの複雑性の可視化
    * 循環的複雑度の可視化
    * 依存関係(不安定性)の分析
    * コードチャーンの分析
* 将来要件の不確実性の可視化
    * ユビキタス言語の作成
    * 非機能要件の具体化
    * 仮説・戦略の透明化


## 外部リソースの活用と内製化
外部リソースを利用すると「取引コスト」が発生するので、その増大には注意を払わないといけない。
取引コストが大きくなる領域は内製化したり、API化やプラットフォーム戦略のような手法で取引コストを削減する。

なお組織設計を間違えると、社内リソースの利用に取引コストが発生するようになる点にも注意が必要。

## 目標管理
生産性の向上に寄与する自律的な人材を育成するには、目標管理が重要。
しかしそれを当初提唱したMBOは誤解されることも多かった。

最近はOKRという手法が注目されている。

## マイクロサービス
コンウェイの法則は、組織の構造はシステムに反映されると指摘するが、それは必ずしも悪いことではなく、適切な組織構造からは効率の良いアーキテクチャーが生まれるとも言える。

これを積極的に狙っていくのがマイクロサービスアーキテクチャーで、ビジネスモデルに基づき編成されたチームの単位でシステムを構築し、システム間をAPIで連携する。これにより、組織の情報処理能力の低下と技術的負債の発生を防ぐことができる。

# 感想
いちばん知りたかったのはアジャイル開発におけるスケジュール管理の手法だったが、この本で紹介されている個別の手法(多点見積り法やプロジェクトバッファなど)についてはだいたい知っていたが、それらを関連付け、体系的に解説してくれているのがありがたかった。

特に不安量を用いたバッファ残の可視化は、今度実践してみようと思う。

ただ、プロジェクトの発注者はプロジェクト開始時点において「いつ何が手に入るのか」を知りたがるものであり、その問いに対して明確に回答する方法がないのは残念だった(分かってはいたけど)。

また、実際のスケジュール管理においては納期が危うくなると、スコープバッファを活用する方法以外にも「人を追加する」という方法が取られることもよくあるが、この本の主題にはそぐわないとはいえ、一言触れられていても良かったなと思う。

あとChapter 5は最後に近づくにつれて駆け足感があったけど、「エンジニアリング組織論への招待」というタイトルが示すとおりの導入本だと考えれば、今後深堀りすべきトピックを網羅してくれているだけでもありがたいと言える。

全体的に、今後あちこちでうんちくをたれるのに良いネタをたくさん仕入れることができた良書でした。