新人「言ってることはわかるんですけど〜、利便性がよくわからないっすw」
君たち新人はいつもそうだね。抽象化についてありのままに伝えると、決まって同じ反応をする。
わけがわからないよ…。
良質なコーディングには必要不可欠でありながら、伝達が非常に難しい「抽象化」の概念。「オブジェクト指向には抽象化が大事だぞ」なんて口にしつつも、実はよくわかってない方も多いんじゃなかろうか。
当記事では、そんな「抽象化がなんとなく腑に落ちない…」というエンジニアを相手にリアルで試してみてウケがよかった例え話をいくつかまとめてみた。
基本的にアカデミックな正確性より勢い優先、その場の雰囲気重視でお送りします。マサカリコワーイ
本題の前に、まずはWikipediaを紐解く
抽象化
抽象化(ちゅうしょうか、英: Abstraction、独: Abstraktion)とは、思考における手法のひとつで、対象から注目すべき要素を重点的に抜き出して他は無視する方法である。
※抽象化 (計算機科学)という記事もあるが、説明上ややこしくなりそうのでプレーンなこっちをチョイスした。
つまり抽象化とは、大事なとこだけ抜き出して他はポイすることである。(雑)
…という説明だけで済めば楽なのだが、これだけで「利便性」まで伝わるかと言えばぶっちゃけ初心者には厳しいかと思う。むしろ「色々捨てちゃうとか不安じゃない???」とか、SAN値を削る無邪気な疑問が出てきて混乱してしまうかもしれない。
大事な点は、「抽象化」はコンピューターの世界に限定された概念ではない、ということ。
本来なら誰しも無意識に使っている考え方なので、現実世界に例えるとなんとなく感覚が掴みやすい。
というわけで、次のような例えを持ち出してみる。
抽象化を「辞書」で例えてみる
よく使われる例だが、プログラムのコードと「辞書」は構成がよく似ている。
例えば、前段で引用したWikipedia(こちらは正確に言えば百科事典だが…)の記事は以下のような構成になっているかと思う。
○○(名前)
××を△△すること。(説明)
「名前」はそのまんま、説明に付けた「名前」を指す。
「説明」は内容の定義、すなわちコードの実装に対応する。
むりやり上記をコード化すると次のような感じだろうか。
function ○○(××) {
return △△する(××);
}
抽象化とは、前述の通り大事なとこだけ抜き出して他はポイすることである。
例えば「白米」という項目に「パンの説明」が併記されていたら、「おいおいそれはないだろ」という話になる。いわばこれが白米の抽象化が効いていない状態だ。
逆に、白米の要素を省きつつパンの説明だけを抜き出して一つにまとめられれば、それはパンの抽象化である。
まだわかりにくい? では、さらに例えを追加してみよう。
抽象化を「コンビニ業務」で例えてみる
以下はコンビニ店長がバイトのA君に「食品の販売期限を確認して欲しい」という指示を出す場面である。果たして前述の「抽象化」が効いてないと、どのような問題が起きるのだろうか?
ケース1:指示内容に余計な要素が含まれるパターン
店長「ちょっとA君!陳列棚のサンドイッチ類が販売期限切れてないか見てくれる?」
A君「はい、ちょっと確認しますね。…ええと、大丈夫みたいです。販売期限が切れてるサンドイッチはありません!」
店長「そうか、それはよかった!…ところで、当然だけどおにぎりも見てきてくれたよね?どうだった?」
A君「え、おにぎりですか?指示されたサンドイッチしか見てませんけど…」
店長「はー…君ねえ、『サンドイッチを見ろ』って言われたらサンドイッチしか見ないの? 同じ陳列棚なんだからさ、おにぎりも見るのが気遣いってヤツでしょうよ。まったく、バイト君は言われたことしかできないから困るよねぇ…」
A君「…(おいおい、さすがにそりゃないだろ…)」
「陳列棚のサンドイッチ類が販売期限切れてないか見てくれる?」という指示が適切に抽象化できていない例である。この例では「陳列棚のサンドイッチ類が販売期限切れてないか見て欲しい」という指示に、文意とは無関係な「おにぎりの販売期限を見る」という内容が含まれている。当然だがそんなもんA君にはわかるわけがないので、店長の意図しない結果=「バグ」が生まれるわけだ。まあ…よく見かける光景ですね…
ケース2:指示内容に含まれる要素を適切に抽象化できていないパターン
店長「ちょっとA君! 垂直な板に別の板を水平にかけ渡した商品を乗せる冷蔵装置に陳列されたイネ目イネ科コムギ属(クロンキスト体系による)に属する一年草の植物から採取した種子植物で有性生殖によって形成される散布体を粉末状に加工し適切量のH2Oを練り込んだ粘弾性があるペーストを炭酸ガスで膨化してから焼成し完成品を薄くスライスした上で間に肉・野菜等を挟んだサンドウィッチ伯爵考案の軽食類が適切に保存された場合において品質劣化による販売上の問題を発生させない期間を超過していないか見てくれる?」
A君「…(何言ってんだコイツ…)」
この例では「陳列棚のサンドイッチ類が販売期限切れてないか見てくれる?」という文面に登場する単語群をWikipedia等を駆使して無理矢理展開してみた。要するに「説明の抜き出し」と「名付け」を無効化した訳だが、こんな簡単な指示ですら一発で難解極まりない指示に変わってしまった。極端だが、いわゆる「スパゲッティコード」に近い状態である。
このような指示(コード)は読み解きの時間が必要となる上、「イネ科…とか言ってたような気がするから、おにぎりを見ればいいのかな…?」等と誤解に繋がり、結果としてバグの原因を生んでしまう。
こうやって現実世界に置き換えると笑い話のようだが、コーディングの世界ではこのくらいヤバい事例はいくらでも存在する。コーダー自身もびっくりするほど気がつかないので、説明に伴う文章(=実装)を一言で言い表せないかどうか積極的に取り組む姿勢が重要となる。
まとめ
- 抽象化とは「大事なとこだけ抜き出して他はポイすること」だよ!
- 抽象化が効いていると、周囲の人に変な誤解を与えずに済むよ!
- 逆に抽象化が出来ていないと間接的にバグを生み出す原因になるからやめようね!
ちょっとした余談:そもそも初心者が「抽象化」を理解できない原因
当記事ほど極端ではないにせよ、コンビニの例えと似た事例はあちこちの現場でよく目にする(特にケース1)。私的な観測範囲で言えば、このような組織文化に対する順応性が高い人ほど抽象化を苦手とする(というより関心を持ちにくい?)傾向があるようだ。
恐らく「コンウェイの法則」と似た原理が働いているのだが、このような場合はマネージャによる「理不尽ではないフェアな組織観」が上手く共有できると状況を緩和しやすい。
参考:コンウェイの法則
「システムを設計する組織は、その構造をそっくりまねた構造の設計を生み出してしまう」 (原文: "Organizations which design systems are constrained to produce designs which are copies of the communication structures of these organizations.")
コードの問題はエンジニアリングだけで解決しようとしがちになるが、マネジメントの観点からアプローチ出来ることがある。権限がある方はお試しあれ。