設計を歪める認知バイアス

こんにちは、リファクタリングが大好きな[ミノ駆動](https://twitter.com/MinoDriven)です。
この記事は [READYFORアドベントカレンダー2021](https://qiita.com/advent-calendar/2021/readyfor) 、5日目の記事です。

# これはなに？

ソフトウェア開発において、設計をないがしろにすると、低凝集密結合な構造に陥り、変更容易性が低下してしまいます。

設計スキルを高め、あるべき構造を設計する……これで解決できるに越したことはありません。
しかし、認知バイアスと呼ばれる心理効果により判断を誤り、良くない設計をしてしまうことが往々にしてあります。

本記事は、設計を歪めてしまう認知バイアスを理解し、設計判断の精度向上を促すことを目的とします。

# この記事のゴール

- 人間の判断を歪めてしまう心理効果「認知バイアス」の存在を知ること。
- ソフトウェア設計も、認知バイアスの悪影響を受けてしまうこと。
- 認知バイアスに振り回されない設計アプローチを身につけること。

# 認知バイアスとは

先入観や思い込み、偏見や誤解などによって非合理的な判断をしてしまう心理現象です。

認知バイアスには様々な種類があります。
たとえば周りの人の行動についついつられてしまう心理効果、同調バイアスがあります。災害が起こったとき、周りの人が逃げている方向についつい自分も行ってしまう、といった行動として現れます。

# 設計を歪める認知バイアスの例

では、認知バイアスがソフトウェア設計に悪影響を及ぼすケースを、6例紹介します。

## ◆アンカリング効果

最初に決めたことが基準となってしまい、その後の判断を歪めてしまう心理効果です。

よく通販番組などでは、最初に高額な価格を提示し、その直後に「今回なんと特別に○割引！！」などと（最初に提示した価格と比べて）安値を提示します。すると、後から提示された価格が割安に感じられます。これがアンカリング効果です。

この販売価格の例では、そもそも最初に提示された価格が妥当かどうかを検証する必要があります。

### 設計で生じる課題

ソフトウェア開発では、クラスの命名でアンカリング効果がよく引き起こされます。

開発初期では、システム化対象の理解が不十分であるために、クラスに大雑把な名前が付けられがちです。
たとえばECサイトで「商品」クラスを設けたとします。
すると、「商品クラスに関係することだから…」と、商品に関するあらゆるロジックが安易に実装されがちです。
予約、注文、配送……あらゆるロジックが詰め込まれ巨大化複雑化してしまうのです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393000/08c643d9-f717-82a0-7e23-1e1347f3bb3d.png)

最初に決めた名前が基準になってしまい、どこにロジックを実装すべきか判断を歪めてしまうのです。
この商品クラスの例では、「商品」の名があまりに意味が大雑把で広すぎて、商品に関する様々な意味を持ててしまいそうになっています。

### どうすればよいか

ゼロベースで名前を見直すことです。
現状の名前を完全否定し、「まっさらな状態であればどう命名するだろうか？」と名前設計し直すのです。
詳しくは下記記事をご覧ください（商品クラスの解説もしています）。

https://qiita.com/MinoDriven/items/37599172b2cd27c38a33

また、目的ベースで名前を設計すると、良い名が見つかりやすいです。
詳しくは下記スライドの目的駆動名前設計をご参照ください。

https://speakerdeck.com/minodriven/buisiness-purpose-system-design


## ◆多義の誤謬

同じ言葉なのに、話者によって前提が違っていて、異なる意味として用いられることを多義の誤謬といいます。

### 設計で生じる課題

同じ名前なのに、何を表現しているかが全く異なるケースが頻繁にあります。
たとえばECサイトでの「User」を考えてみます。

「User」は何を意味するのでしょうか。
ある場面では商品の買い手、またある場面では商品の売り手、またある場面では管理者…というように、ECサイトには役割の違う人物が複数登場します。「User」が意味するものがコロコロ変わりますね。

ところがそれらをたったひとつの「User」モデルで実装されてしまうケースが実際にあります。
どんな弊害が待ち受けているのかは次の動画をご覧いただければわかります。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">クソコード動画「Userクラス」 <a href="https://twitter.com/hashtag/DXD2021?src=hash&amp;ref_src=twsrc%5Etfw">#DXD2021</a> <a href="https://t.co/JOIIl8IuwS">pic.twitter.com/JOIIl8IuwS</a></p>&mdash; ミノ駆動 (@MinoDriven) <a href="https://twitter.com/MinoDriven/status/1380773721032433674?ref_src=twsrc%5Etfw">April 10, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

モデルが混乱して使いづらくなったり、バグの原因になったりします。

### どうすればよいか

言葉の裏にある意図や目的を洗い出しましょう。
同じ言葉でも意図や目的が異なるものは、別々の概念、別々のモデルとして分離しましょう。

ユビキタス言語とは、意図を共有するための言葉で、ドメイン駆動設計（DDD）に登場します。
DDDでは、関係者同士でユビキタス言語を用いて話し、意図を共有することの重要性を説いています。

詳しくはこちらのスライドをご覧ください。

https://speakerdeck.com/minodriven/kusokododong-hua-userkurasu-dekao-eruji-shu-de-fu-zhai-jie-xiao-falseguan-dian


## ◆早まった一般化（早すぎる抽象化）

ごく少数の事例から、「これが一般的な性質だ」と誤った性質を推論することを早まった一般化と言います。

たとえば多くの男性にフラれた恋多き女性がいるとします。
「A君はひどいヤツだった」
「B君はひどいヤツだった」
「C君はひどいヤツだった」
「たから男はみんなひどい」

A君、B君、C君がたまたまひどいヤツであっただけで、世の中全ての男性がひどいという話ではないはずです。
これが早まった一般化です。

### 設計で生じる課題

ソフトウェア開発では「早すぎる抽象化」という形で現れます。

重複コードとは、あるコードと同じ、または酷似したコードのことです。コードクローンとかコピペコードなどとも呼びます。
重複コードがあると、仕様変更時に重複箇所の全てを修正しなければなりません。修正漏れがあるとバグ化します。
したがって、処理を共通化するなど重複の解消が必要です。

しかし、構造が似ているだけで、共通化してはいけないものもあります。
そうしたコードを無理に共通化すると密結合に陥り、逆に変更容易性を貶めてしまいます。

「早すぎる抽象化」の弊害を描いたのが、私が制作した動画「共通化の罠」です。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">クソコード動画「共通化の罠」 <a href="https://t.co/MM750CNXc2">pic.twitter.com/MM750CNXc2</a></p>&mdash; ミノ駆動 (@MinoDriven) <a href="https://twitter.com/MinoDriven/status/1127539251761909760?ref_src=twsrc%5Etfw">May 12, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

### どうすればよいか

有名なソフトウェア原則に、DRY原則があります。
DRY原則は「コードの重複を許すな」といった解釈で広まっているようですが、そうではありません。

「知識の重複を許すな」すなわち
「ビジネス概念の重複を許すな」が主旨として近いです。

DRYにすべきはビジネス概念単位です。
同じようなロジック、似ているロジックであっても、概念が違えばDRYにすべきではないのです。
詳しくは下記記事で解説しています。

https://qiita.com/MinoDriven/items/76307b1b066467cbfd6a

## ◆レッテル貼り

独断や偏見、先入観で決めつけてかかり、断定的に性質を評価することをレッテル貼りと言います。
たとえば平日昼間に私服で街を歩いている男性を指して「あの人は無職だ」と決めつけてかかるのがレッテル貼りです。リモートワークで昼食を買いに外出しただけかも知れないのに、ひどい話ですね。

### 設計で生じる課題

「私はエンジニアですよ？技術には興味ありますけどビジネスには興味ありませんから。仕様はビジネス側で考えて下さい」
…こういう趣旨の発言をしているエンジニアさんが、たびたび見受けられます。

- エンジニアは技術だけやる人
- ビジネスサイドはビジネス考えたり仕様を考える人

…こういう思い込みはレッテル貼りの一種です。

エンジニアリングにおけるレッテル貼りは、設計品質を貶める悪しき方向に働きます。

変更容易性の設計には、単一責任原則（SRP）が重要です。
SRPを遵守するには、ビジネス概念の把握が必須です。
ビジネス理解が薄いと、ビジネス概念を詳細に把握できなくなります。
すると責務が多重になって密結合になり、変更容易性を貶めてしまいます。

詳しい理由は下記記事をご覧ください。

https://qiita.com/MinoDriven/items/76307b1b066467cbfd6a

### どうすればよいか

エンジニアリングは、プログラミングだけしていれば良いといった単純な仕事ではありません。
技術力を専門的に発揮しつつも、ビジネスを成功に導くために、様々な力を複合的に発揮し仕事を組み立てていくものです。

アーキテクトは、ビジネス戦略を実現するアーキテクチャを設計する職種です。
アーキテクトの職務遂行にはビジネス理解が必須です。

アーキテクチャといった大粒度でなくとも、クラス単位でも同じことが言えます。
高い変更容易性を発揮するには、エンジニア一人ひとりがビジネスを理解し、モデルに落とし込み、SRPを遵守したクラス設計を目指すことが大事です。

## ◆現状維持バイアス

人の心理には、メリットよりデメリットを過大評価しようとする働きがあります。
何か行動や変化を起こそうとする際、メリットとデメリットを比較します。
しかしデメリットが過大評価されてしまうために、メリットを上回ってしまいがちです。
そのため、行動に起こさず現状を維持しようとします。
これが現状維持バイアスです。

### 設計で生じる課題

リファクタリング文化のない現場にリファクタリングを導入しようとしても、かかるコストや失敗した場合のリスクばかりが過大に不安視され、なかなか導入に至らない、というケースがあります。
特にレガシーな現場においては。

### どうすればよいか

デメリットを小さくし、メリットを大きくすることを伝えます。
たとえば以下です。

- スモールステップで実施し、ひとつひとつの影響を小さくする方針であることを伝える。
- 実施の費用対効果を考慮する。変更頻度が高い箇所を狙い、コスト面で優れていることを伝える。

## ◆分析麻痺症候群

分析ばかりやりすぎて、分析自体が目的化してしまったり、分析結果が現場と乖離した役に立たないものになってしまう事象です。

### 設計で生じる課題

ソフトウェア品質は価値を高める上で重要です。
品質を高めるために設計します。

設計には、どういった要件を満たせばよいか定めるために、背景の調査や分析を行います。

また、巨大なレガシーシステムの技術的負債を解消するには、本来理想的はどういう構造であるべきか再設計が必要です。
そのために、ソースコードやシステムで扱っている概念を調査・分析します。

しかし、分析ばかりに何ヶ月も時間がかかり、開発やリファクタリング実装にまったく取り掛かれないといったことがあります。

分析が終わった頃にはビジネス要件がすっかり変わってしまって、分析結果が使い物にならない場合すらあります。

### どうすればよいか

分析麻痺症候群に陥っているとき、期限と目的を見失っていることがほとんどです。
期限と目的を定めましょう。

ある程度の分析が済んだら、早めに手を動かして実装を進めます。
実装してみると、机上分析では分からなかった事柄が分かったりします。しかも頻繁に。
得られた知見を設計にフィードバックします。

そもそも設計は1回で終わりではありません。
何度もフィードバックを重ねることで、少しずつ精度が上がっていくものです。
フィードバックサイクルを回すことを前提に設計を進めましょう。

# まとめ

以上、設計を歪める認知バイアスの6例を紹介しました。
しかしこれはごく一部に過ぎません。もっともっと多くの種類の認知バイアスがあります。
ご興味のある方は調べてみましょう。
「あ、これは開発や設計に影響があるかも」と、新たな発見があるでしょう。

設計は、システム化対象のビジネス概念を分析し、ロジック構造に落とし込む判断の連続です。
判断がいびつだと、ロジック構造も当然いびつになります。

設計が上手くいかないとき、「もしかして認知バイアスの影響を受けているのでは？判断がゆがんでいるのでは？」と、自己の判断を見直してみると、設計の良い手がかりが見つかるかもしれません。

# 参考文献

[書籍『情報を正しく選択するための認知バイアス事典』](https://www.amazon.co.jp/dp/4866801239)