ソフトウェアにおける
複雑さとは何なのか?
kawasima
「複雑さ」を定義する
『A Philosophy of Software Design』John K. Ousterhout
● 「複雑さ」は理解や修正を難しくするソフトウェアの構造に関連したもの
○ (定義とし書かれているのはこれくらい
)
● 複雑さだと…
○ 単純な変更でもいろんな場所のコードを修正が入る
○ 認知負荷が高い
○ 分からないことが分からない
● 複雑さの原因は…
○ 依存性
○ 不明瞭さ
『Domain Driven Design』Eric Evans
● ビジネスルール間に矛盾が発生すると複雑
● 同じ言葉に違う意味を持たせていると複雑
● Value Objectで良いものにIDを持たせるのは複雑
一貫性がないと複雑
→ ユビキタス言語?
あいまいでよく分からない…
複雑さの言い換え
● 使いにくい
● 理解が難しい
● メンテしにくい
● 長ったらしい
● 覚えきれない
● 実行が難しい
● 管理できない
● 色々混ざっている
● たくさんの要素がある
● 一貫性がない
● 込み入ってる
● ゴテゴテしている
● 不透明
John Cutlerさんのツイートの裏返し
Simple Made Easy
https://github.com/matthiasn/talk-transcripts/blob/master/Hickey_Rich/SimpleMadeEasy.md
Rich Hickey定義のComplexity
● 複数の役割
● 複数のタスク
● 複数の概念
色々混ざっている
一貫性がない
もう1つの複雑さ
マイクロサービスの各サービスは Simpleでも…
要素が多くそれらの関係性把握が難しい
込み入っている
たくさんの要素がある
2種類の複雑さ
● 単一のコンポーネントに内包される複雑さ
○ 1つのエンティティ、1つのクラス、1つのfunctionに複数の責務・概念が混ざっている。単
一責任原則(SRP)に違反した状態
○ Simpleの対義語としてのComplexの意
● コンポーネント数が多いことによる複雑さ
○ エンティティやクラス、functionの数が多く、それぞれの役割や関係性を理解するのが厄
介。
○ ややこしい意としてのComplicated
2種類の複雑さは可換性がある
つまり、巨大なエンティティや巨大なクラスを、 1つ
の責務・概念に分解しても、複雑さの総量が変わる
わけではない。
『データモデリング入門』渡辺幸三
何をもって 「ひとつの情報のまとまり」とみなすかを明確にしたうえで、それぞれのテーブルにひとつの情報
のまとまりだけを置くように配慮する。このことによって、取り分け手順の複雑さが「テーブルの数の増加」と
いう複雑さに移行する。その結果、指示を用意したり改善したりするための手間が減る。
ただし2つの複雑さは対称ではない
❶の注文には、どういう概念が含まれるかパッとは分からない。
ここまでの整理
込み入っている
たくさんの要素がある
色々混ざっている
一貫性がない
理解がしにくい
メンテがしにくい
長ったらしい
覚えきれない
単一のコンポーネントに
内包される複雑さ
コンポーネント数が多いこ
とによる複雑さ
これら「複雑さ」から
導かれる効果
生来的複雑さを選択する
ここまでは、ソフトウェアが表現するビジネスの持つ
生来的複雑さが、変わらないことを前提としての
話であった。
生来的複雑さは、ビジネス要求によって変わるが、モデルの柔軟性次第でも変わる。
『Analysis Patterns』Martin Fowler
● システムに柔軟性を持たせすぎると、システムが複雑になりすぎてしまう。
● エンジニアリングは人工物の構築
, 維持にかかるコストと、それが提供する機能とのトレードオ
フを必要とする。
『Clean Code』Uncle Bob
● 道具は道具箱の中に整理され、それぞれが明確に定義されラベル付けされた部品を含む多く
の小さな引き出しが必要なのか?それとも、何でも放り込んでおけるような引き出しがいくつか
欲しいのか?
● 複雑さを整理するために、適切なサイズの前者が必要
柔軟性と複雑さ(単純さ)のトレードオフ
例えば、「ピザ」のモデルを考える
Cheese Pizza {
price: MonetaryAmount;
cheese: Weight;
}
Pizza {
price: MonetaryAmount;
dough: Dough;
topings: Topping[];
}
Product {
price: MonetaryAmount;
ingredents: Ingredient[];
}
柔軟性
複雑さ
(2種類の複雑さの総量 )
(潜在的に)表現可能なモデルの範囲
A) ピザの種類ごとに型を用意する B) ピザで1つの型を用意する C) ピザ以外の商品も表現できるモデル
Case1 単純だが柔軟性にかける
仕様の変更時に、プログラムの修正が発生する。
連れてテーブルの変更も。
→ が、このコストは年々小さくなるだろう
おそらく、この設計自体が抽象的思考に至りにくいこと
が、ビジネス側にも影響を与え、水平思考に繋がらない
ことが最大の問題になると思う。
Cheese Pizza {
price: MonetaryAmount;
cheese: Weight;
}
Case2 柔軟だが決まっていないことが多すぎる
Ingredentsの組み合わせには、多くの制約が存在する
ことが考えられるが、その制約の設計やテスト容易性を
確保することが困難。
設計時点で、モデルにその自由度が必要なのか? 過剰
な柔軟性であると、Martin FowlerやUncle Bobの言う
通り、現時点では不必要な複雑さを導入してしまってい
ることになる。
Product {
price: MonetaryAmount;
ingredents: Ingredient[];
}
複雑さのハンドリングガイド
● 複雑さには2種類ある
○ 単一のコンポーネントに内包される複雑さ
○ コンポーネント数が多いことによる複雑
● 単一のコンポーネントに内包される複雑さは、分解してみないと正体が見えない
(すなわち実装どうするかによらず、まず正体を明らかにすることが必要
)
● 2種類の複雑さの総量は、通常業務の複雑さによって決まるが、モデルにどこまでの柔軟性を
持たせるかによっても変わってくる。
(適度な柔軟性と複雑さを選択しよう
)

ソフトウェアにおける 複雑さとは何なのか?