メタファー思考とオブジェクト指向

この記事は[SRA Advent Calendar 2016](http://qiita.com/advent-calendar/2016/sra)の25日目の記事です。

## ユビキタス言語
最近、DDD（Domain-Driven Design ドメイン駆動設計）が話題になっているのをよく見ます。
DDD自体は結構前からある手法であり、書籍「エリック・エヴァンスのドメイン駆動設計」の原著は10年以上も前に出版されたものです。
そのDDDの中で「ユビキタス言語」というのが出てきます。
開発ではチーム全員が共通の言語を使おうというものですが、単に用語を統一すればいいというものではありません。
ここでいう**チーム全員**というのはもちろん、ユーザを含め設計者やプログラマなどの開発者全員です。
こういうと「そんなの当たり前だよ。ウチは上流工程で用語集を作成して全員で共有してるよ」と思われるかもしれませんが「ユビキタス言語」というのは「ユーザが使っている用語を開発者が共有する」というのとは違います。
DDDでなぜユビキタス言語というものが必要かというと、それは**モデルを共有する**からです。
チームはユビキタス言語という共通言語を使うことでモデルについて共通認識を行います。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">ドメインモデリングにおいては、概念を実装から切り離してはならない。優秀なドメインモデラは、経理担当と一緒にホワイトボードを使うこともできれば、プログラマと一緒にJavaを書くこともできる（マーチン・ファウラー　「エリックエヴァンスのドメイン駆動設計」の序文）</p>&mdash; 佐々木和繁@ℵ (@kazsharp) <a href="https://twitter.com/kazsharp/status/119429108605263873">2011年9月29日</a></blockquote>

このツイートは私が「エリック・エヴァンスのドメイン駆動設計」を読んだ時のツイートですが、引用したマーチン・ファウラーの序文はDDDの本質を端的に表していると思います。
DDDでの「モデル」は概念から実装まで一貫して採用され、それはチーム全員で共有されるものです。
つまり、そこには設計者や実装者が行った工夫も盛り込まれており、その内容を誤解なく共有するには共通の認識を持った言語で統一する必要があります。
ドメインエキスパートは普段ユーザが使っている用語であっても、それがドメインを理解するのに相応しくないと感じたら別の用語を検討しなければいけません。
開発者は設計・実装に支障をきたしそうな曖昧な用語があれば指摘するべきです。
そうして作り上げた共通言語が**ユビキタス言語**です。

## メタファー
DDDのユビキタス言語について知った時、私はXP（extream programming）のプラクティス「共通の用語」を思い出しました。
「共通の用語」は元々「メタファー」というプラクティスでしたが、うまく機能しないことが多かったようで「共通の用語」に変更されました。
私は幸い、日本でXPが話題になり始めた頃にXPを適用したプロジェクトに参加することができたのですが、その時の経験から考えると、以下のような理由でメタファー・プラクティスがうまく機能しなかったのではないかと思っています。

* メタファーという言葉に文学的な響きを感じてしまう
* どんな用語もメタファーを見つけようと躍起になる
* いいメタファーがなかなか思いつかず時間がかかってしまう

「メタファー」という言葉の響きに引きずられてしまいがちですが、目指すところはDDDのユビキタス言語と一緒ではないでしょうか。
そう考えると、美しい表現にこだわったり無理にメタファーを考えたりせず、全員が理解しやすい表現を見つけやすくなるのではと思います。

## メタファー思考
ここで一旦DDDとXPのことは棚上げしておいて、「メタファー」について考えてみます。

というのも最近、同じ会社の人に[「メタファー思考」](https://www.amazon.co.jp/dp/4061492470)という本を借りて読んだところなのです。

この本は**目玉焼きはメタファー**であるという話から始まり、普段我々が意識しないようなレベルまで徹底的にメタファーについて考察します。
また、英語との比較なども行い、メタファーが言語の特性によらず人間の認知活動から自然と発生することも示します。
先ほど「メタファーに文学的な響きを感じてしまう」と述べましたが、この本の中では「科学とメタファー」の関係についても述べられています。
「科学とメタファー」と聞くと、「あいまいな表現をゆるさない厳密な定義を好む科学とメタファーは相反するものでは？」と思う人もいるかもしれません。しかし本著書はそのような考えも確かにあるが、「電池」や「電流」、「原子のモデル」などの例を挙げ科学にもメタファーが取り入れられていることを説明しています。
また、

>かつての光の性質についての論争――光は粒子なのか波動なのか――も、メタファーの論争であった。粒子と見立てた方がより多くの光の現象を統一的に説明できるのか、それとも波動と見立てた方がよりいっそう有効な説明が与えられるのかという争いであった。

と量子論を語る時に必ず出てくる光の二重性についての論争は**メタファーの論争**であると述べています。

## オブジェクト指向

ここで先ほど「棚上げ」しておいたDDDとXPについて話を戻します。
（「メタファー思考」を読んだらこの「棚上げ」もメタファーだと気づきます）

DDDもXPもその前提として「オブジェクト指向開発」があります。
関数型プログラミングが流行りだしたおかげで、オブジェクト指向についての関心が薄れていますが、優れた設計・プログラミングを行おうとするとき、オブジェクト指向の考え方は今でも十分役に立ちます。
メタファーの話から急にオブジェクト指向の話になったと思われるかもしれませんが、先述の「メタファー思考」という書籍の中で「メタファーとは≪見立て≫と考えると分かりやすい」との記述があり、私はこの「**見立て**」というのはオブジェクト指向でも重要な考え方の一つだと思っています。
オブジェクト指向で欠かせない抽象化や汎化、さらにはクラスを抽出すること自体が見立ての一種だといえるのではないでしょうか。
例えば、易しい例で言うと「契約社員クラス」と「正社員クラス」があり、汎化で「従業員」クラスを作った場合、「契約社員」と「正社員」を区別せず「従業員」だと**見立て**ていることになります。
また、「エレベーターの人の乗り降り」を「倉庫の入出庫」と同じ考え方で設計するのは少し高度な**見立て**だと言えます。
「従業員」の例ではメタファーとは言えませんが、「倉庫の入出庫」はメタファーでありユビキタス言語を考えるときのヒントにもなるかもしれません。

## おまけ
オブジェクト指向の考え方として**見立て**が大事だという話をしましたが、私たちはこの**見立て**について訓練する機会が度々あったはずです。
国語の授業でメタファーや種々の比喩表現を勉強してきたのはもちろん、数学でも**見立て**る学習をしています。
例えば、因数分解で
![metaphor001.png](https://qiita-image-store.s3.amazonaws.com/0/100799/95588e19-9ac3-51b1-9107-73bb81de48e7.png)
という公式を覚えて
![metaphor002.png](https://qiita-image-store.s3.amazonaws.com/0/100799/cfdbed2e-38b5-550f-fb45-e1b752b19028.png)
と応用するには**2x**を**a**、**3y**を**b**と**見立て**る必要があります。
さらに
![metaphor003.png](https://qiita-image-store.s3.amazonaws.com/0/100799/55c1508a-1e46-60de-efb5-7e399555f00a.png)
などは**2a+3b**を**a**、**4x+5y**を**b**と見立てています。
他にも英語の授業で**節**や**句**などを**カタマリ**でとらえて単純な文型に当てはめるのも**見立て**の訓練になるのではないでしょうか。

このようなことを考えると「学校で勉強する内容も大事だったんだなあ」と思いますし、「どんな勉強も決して無駄ではないんだなあ、これからも色々勉強したいなあ」という気になります。
プログラミング言語についてはもちろん、英語でも数学でも音楽でもストⅡでも山登りでも勉強することは無駄ではないと思います。
もしこの記事を読まれた方が「よーし、俺も勉強するぞー」という気になったのならとても嬉しいです。

最後まで読んで頂きありがとうございました。
メリークリスマス。そしてよいお年を。