ブルックスのいう
銀の弾丸とは何か?
kawasima
kawasima
アーキ部#15
“生産性、信頼性、簡便性において、10年以内に1桁の向上を
約束するような技術や経営手法の開発は、一つもない”
Frederick P. Brooks
Mythical Man-Month, The: Essays on Software
Engineering, Anniversary Edition, 2nd Edition
Chapter 16 No Silver Bullet—Essence and
Accident in Software Engineering
ソフトウェア開発の難しさ
本質的 偶有的
存在するが必須でないもの
ソフトウェア開発に本来的に
備わっているもの
「偶有性」はアリストテレスの定義を参考にしている
実体 本質的
量 偶有的
質
関係
場所
時間
位置
所有
能動
受動
「偶然有る」ではなく
「偶々有る」の意
本質的難しさ
複雑さ
適合性
変動性
目に見えない
ソフトウェアは自然科学と違い恣意的に決められたルールや
制度に合わせなきゃいけない。
ハードウェアと違い変更がなされる
ゆえに設計プロセスもコミュニケーションも難しい
本質的に多くの状態を持つ
これらに効く本質的な 銀の弾丸がない、と言っている
過去のブレイクスルーで偶有的難しさは一定乗り越えてきた
高水準言語
タイムシェアリング
統合プログラミング環境
ディスク、メモリなどを意識せずに高い抽象レベルのところで
プログラミングできるようになった
コンパイルの待ち時間で思考が中断されることがなくなった
UNIXのパイプ&フィルタなど、プログラム同士を組み合わせ
て使えるようになった
「銀の弾丸はない」と言い切る根拠
本質的 偶有的
偶有的難しさはブレイクスルーできる可能性があるが、本質的難しさは無理
この比率、偶有的難しさが 90%以上含まれているんだったら生産性一桁あげれる可能性が
あるが…
そんなことはないよね! という主張
ブルックスを引用するならば…
「要はバランス。絶対的な正解はない。銀の弾丸はないってことよ」
「お金で開発環境を整備した方が良い。パフォーマンスチューニングできる人を雇うより
Exadata買った方が安上がり。銀の弾丸より 金の弾丸」
という言い回しは、ブルックスの意図とはズレていると言える。
後続の研究
Out of the Tar Pit
※「人月の神話」の1章のタイトルがタールピットであることを踏まえている
”複雑さ、適合性、変更可能性、不可視性の4つの特性のうち、私たちは複
雑さが唯一の重要なものであると考えている。他の特性は、複雑さの形態
として分類されるか、またはシステムの複雑さのために問題が発生するた
めに問題があると見なされる可能性がある。”
https://curtclifton.net/papers/MoseleyMarks06a.pdf
本質的複雑さと偶有的複雑さ
状態
状態から
直接計算
するロ
ジック
https://tech.uzabase.com/entry/2021/05/20/141950
本質的複雑さ
コントロール
導出でき
る状態
偶有的複雑さ
偶有的複雑さは究極理想環境では無くなるもの
と考えると良い
● どんな検索も一瞬で返すマシンや無限のメモリ空間など
● 判断ミスをしない設計者
現実にはそういうものが存在しないので、トレードオフを考えつつ意思決定 (偶有的複雑さ
を抱える)ことを決めていく。
偶有的複雑さの例①
取引を集計しさえすれば、現在の残高は
求まるので、口座エンティティには「残高」
は不要。
…なのだが、実際はその算出にそれなりの
計算量が必要なので、口座に「残高」を持
たせる。
そうした途端に付随して、
● 残高更新時の排他制御
● 取引の集計と残高のズレのチェック
(リコンサイル)
など、発生しさらなる複雑さを生む要因に
なる。
偶有的複雑さの例②
コントロールフロー
手続き型のプログラミングスタイルだとコード順に
依存するので思わぬ問題に遭遇することがある。
https://twitter.com/t__keshi/status/1635267214008897537
偶有的複雑さの例③
https://www.slideshare.net/kawasima/ss-255489610
偶有的複雑さの対処は変わりゆく
本質的複雑さへのアプローチ
本質的複雑さには対処のしようがないのか…?
シンプルの対義語としての「複雑」
● 1つの役割
● 1つのタスク
● 1つの概念
● 複数の役割
● 複数のタスク
● 複数の概念
シンプル 複雑
https://github.com/matthiasn/talk-transcripts/blob/master/Hickey_Rich/SimpleMadeEasy.md
要素数が多いのも「複雑」
要素数が多く、それらが相互作用しあう。
2種類の複雑さ
● 単一のコンポーネントに内包される複雑さ
○ 1つのエンティティ、1つのクラス、1つのfunctionに複数の責務・概念が混ざっている。単
一責任原則(SRP)に違反した状態
○ Unknown Unknowns (理解困難) [A Philosophy of Software Design]
● コンポーネント数が多いことによる複雑さ
○ エンティティやクラス、 functionの数が多く、それぞれの役割や関係性を理解するのが厄
介。
○ 認知負荷が高い (把握難しい) [A Philosophy of Software Design]
これら相互に変換可能
本質的複雑さ保存の法則
巨大なエンティティや巨大なクラスを、 1つの責務・
概念に分解しても、本質的複雑さの総量が変わる
わけではない。
非対称な理解可能性
❶の注文には、どういう概念が含まれるか分からない。
まず目指すべきは:
1つのエンティティに含まれる複雑さを最小化すること
● ドメインに含まれる責務・概念を可
視化する
● 理解のためであり、実装はそれか
ら考えれば良い。
● 変更容易性は「理解しやすさ」の結
果であり、設計の第一目的ではな
い
コンポーネント数の多さに起因する複雑さ
(高い認知負荷)にどう対処するか?
古くより色々提唱されてきた
● 分割統治
○ Bounded Context
● 抽象化
抽象化出来ていないと認知負荷が高まる例
属性値の組み合わせた結果だけが残っていて、
組み合わせに関する制約や、属性間の依存関係
などが抜け落ちている。
抽象化出来ていないと認知負荷が高まる例
http://www.slideshare.net/kawasima/ss-26968240
同じく属性値の組み合わせた結果だけが残る
抽象化出来ていないと認知負荷が高まる例
https://www.smbc.co.jp/hojin/eb/computerbanking/resources/pdf/gaikokusoukinirai_zenginformat.pdf
業務の用語とシステム都合の用語が混じり合う
と、さらに凶悪になる
抽象化に必要なこと
type Suit = "Club" | "Diamond" | "Spade" | "Heart"
type Rank = "2" | "3" | "4" | "5" | "6" | "7" | "8"
| "9" | "10" | "Jack" | "Queen" | "King"
type Card = [ Suit, Rank ]
type Hand = Card[]
type Deck = Card[]
type Player = { name: string; hand: Hand }
type Game = { deck: Deck; players: Player[] }
type Deal = (deck:Deck) => [ Deck, Card ]
type PickupCard = (hand: Hand, card: Card) => Hand
前回のアーキ部
『Domain Modling Made Functional』の手法で本質的な状態とロジック を記述する
のがオススメ。日本語訳に期待!

ブルックスのいう銀の弾丸とは何か?