四十三庵

蔀の雑記帳

複雑なものに対処するための方法

仕事で、複雑なものと向き合うことが多い。
たまにわざと複雑にしてるんじゃないかと思うくらい、複雑になっている。
そこで、複雑性を一般化して、それに対して対処法を考えてみた。

基本的には「ソフトウェアの複雑性」のイメージで書いてるが、他のものにも応用できるかもしれないので、
敢えて限定しないで書いてみる。敢えて、ね。

  • 複雑性を六つの要素に分解

複雑性と言っても、色んなパターンがある。
単に規模が大きくなりすぎて、全体が把握できなくなっているのか、
テキトーに作りすぎて、しっちゃかめっちゃかになっているのか、色々あると思う。

つらつら考えるに、複雑性は六つの要素に分解できる。
(後で増減あるかもしれない)
f:id:st43:20150201105004j:plain

  1. 多量性
  2. 多種性
  3. 曖昧性
  4. 新規性
  5. 非論理的
  6. 非感覚的

この六つの要素が絡み合って、複雑なものが生まれる。
要素1〜3は中身の問題で、4〜6は外見の問題に中分類できるかもしれない。
複雑性の本質は、やっぱり要素1〜3だと思う。
要素4〜6は、ここに気をつけると複雑性を人間が理解しやすくなるというポイントになるのかな。
各要素を簡単に説明する。

1.多量性
情報量が多いと、当然複雑になる。
人間の記憶力には限界がある。
どんなに頭のいい人間でも、六法全書のすべてのページを暗記するようなことは出来ないだろう。
ソフトウェアで言うと、単純にシステムの規模がデカいとか、ソースコードが長いとか、そういうのにあてはまる。

2.多種性
情報量が多くても、パターン化されているのであれば、まだ処理しやすい。
問題は、全く不規則な場合だ。
たとえば、コンビニチェーンの経営者が、100店舗経営していて、
その店の営業時間をすべて把握したいというときに、
「90店舗は24時間営業で、10店舗は田舎で夜中は客が来ないので、7時〜21時です」
と説明されたら、2パターンしかないので、「100店舗の営業時間」という情報量としては多いものを頭に入れることが出来る。
しかしこれが、
「パターンは20個あります。まず24時間営業はこの表1に載せた20店舗のみです。
6時〜24時の営業が15店舗あります。これは表2です。
この35店舗以外は、平日と休日で営業時間を変えています。
パターン3は……」
などと言う話だったら、到底頭に入れるのは不可能だ。
ソフトウェアでも、DRY原則が守られていないコードだと、
至る所にコピペして、ちょっとだけ書き変えた素敵なプログラムがあって、
運用保守しなければならない人々を辛い気持ちにさせる。

3.曖昧性
曖昧なものが含まれていると、複雑化する。
身近な例で言うと、コンビニでバイトのシフトを組むときに、
バイトが時刻通り絶対に来て、また客の人数も波がなければ、何も悩むことはない。
けど実際は遅刻や欠勤もあるし、急に客がたくさん来て、レジに並びだすかもしれない。
ソフトウェアでは、ブラックボックス化したプログラムが動いてるシステムで、
新しく何か追加しようとした場合を考えるとよい。

4.新規性
新しいものは複雑に見える。
たとえばセブンイレブンの棚が突然変えられて、全面タッチパネルになって、
商品をパネルで選択して、買い物カゴの代わりに専用端末で受信するような仕組みになったら全国で大混乱が起こるだろう。
経験の力というのは大きい。
ソフトウェアでも、可能な限り、既存のコードを活かした方が、現場のためにはよい。

新規性によって生まれた「例外」が、要素2の多種性につながる場合も多い。

5.非論理的
論理的でないものは、複雑に見える。
何かの表があったとして、名前の順に並んでないとか、数字が順番になっていないとか、
論理的に整理されていないと、人間にとって理解しづらい。

個人的な経験から言うと、非論理的な設計になっているときは、
だいたい歴史的な経緯が絡んでる場合が多い気がする。
「これ、なんでいきなり4番からはじまってるんですか?」
「ああ、それ昔は1〜3番があったんだよ。ただ廃止になって……」
みたいな。

6.非感覚的
感覚的でないものは、複雑に見える。

コンビニの商品を陳列するときに、
「おにぎりを賞味期限見て、切れてたら捨てて新しいの出して」と指示されれば、
大雑把な指示ではあるが、何となく理解できる。
「賞味期限が切れてたら、といいますが、賞味期限一分前のやつは捨てますよね?
賞味期限何分前まで捨てたらいいですか? そこまで指示してくれないとわかりません」
みたいな奴もいるけど、ちょっとめんどくさい。
そんな頭が固い奴のために、
「商品コード10000〜19999までの商品を、マニュアル27ページ3項目の「消費期限について」を参考にして、
今から13:30の間に消費期限チェックを行い、販売OKの商品はそのままにして、販売NGの商品は廃棄し、
新たな商品と交換してくれ。なお、その作業中にレジに二人以上の客が並んだ場合は、ヘルプでレジに入ってくれ」
と指示を出したら、正確ではあるかもしれないが、全然理解できない指示になるだろう。
なぜわからないかというと、非感覚的だからだ。

コンピューターも、GUIになってから、感覚的になった。
論理的に考えたら、コマンド叩いて、アプリケーションを起動する処理と、
デスクトップのアイコンをクリックして、アプリケーションを起動するのも、
コンピューターから見たら同じ処理だし、デスクトップやウィンドウをデスクトップに表現する分、
GUIの方がコンピューターの処理は増える。
けれどもGUIが普及したのは、明らかにGUIの方が感覚的で、わかりやすかったからだ。

  • 複雑性への対処法

さて、6つの要素にわけたところで、それぞれへ対処法を考えよう。

1.多量性
情報量が多ければ、分割するしかない。
「困難は分割せよ」というデカルトさんの教えに従おう。
巨大なものも、最小単位に分割する。

2.多種性
種類が多いときでも、パターン化で対応するしかない。
なるべく法則を見つけて、グループ化しよう。
可能であれば、パターン自体を減らせるとよい。

3.曖昧性
曖昧性については、まずは調査することだ。
来店客数を調査して、グラフにして見る。
ブラックボックス化してるプログラムを調べ、理解する。
そうして曖昧性を排する。
完全に0には出来ないだろうけども、0に近づけることはできる。

4.新規性
標準化を図って、なるべくパターンに落としこむこと。
要素4〜6すべてに言えることだが、既に完成したものから、
これらの要素を排除しようとした場合、作りなおす(リファクタリングする)しかない。

5.非論理的
より論理的に作りなおす。

6.非感覚的
より感覚的に作りなおす。

  • まとめ

書いてきたことをまとめると、以下の表のようになる。

多量性 最小単位に分割
多種性 パターン化
曖昧性 調査
新規性 リファクタリング
非論理的 リファクタリング
非感覚的 リファクタリング


複雑性を排するために重要なことは、シンプルなものを作るためにも重要だ。
抽象化して書いてる分には、ああだこうだと理想を言えるけど、
実際に何か作ってみて、年月が経って、規模がデカくなってくると理想が貫けなくなる場合も多いのが現実なんだろうな、とも思う。
(了)