原始のドメイン駆動設計はどこから始まったのか？


# エバンスDDDでは説明できない

何もエバンス氏のドメイン駆動設計が時代に合わなくなったわけじゃないんです。
今日でもアジャイルとかスクラムとかとの親和性は高いと思っているんですが...
昔からいわゆる青本を見て「**モデル駆動設計に偏っているなぁ**」と思っていたんです。
で、最近、リファクタリングの観点リストをまとめる機会があって、その時にプログラミング言語の特性について色々と考えたんですが、その時に自然言語を含む「言語」と「モデリング」の関係を説明するには「ユビキタス言語」の解釈では全然足りなかったんですよ。

エバンス氏は「ユビキタス言語」について**設計者**が**ドメインエキスパート**と**直接**話をしながら**モデリングを行う**ためのツールと捉えていて、これが必要な理由を**伝言ゲーム的な認識齟齬を防止するため**としています。

そのこと自体は良いのです。ただし、このユビキタス言語の言葉を**プログラムの中でも使うことを推奨**してるのですが、これって言語学の用語で**ピジン語** [^1] と呼ばれる自然言語（人の言語）のかなり特殊な使い方を推奨してるってことになるんですよ。

でもピジン語って**文法がない**から、ユビキタス言語ではドメインエキスパートと設計者のコミュニケーションと、プログラム・コードの間で**文としての齟齬があっても構わない**ってことになるんです。そんなわけないですよね。もちろん仕事では大人な対応をするから、これが問題になることはないはずなんですが...

どうせなら矛盾の少ない体系を使いたいですよね？

というわけで**越境**を宣言します。

# そもそも何故ドメイン駆動設計はユビキタス言語とモデル駆動設計で構成されるのか？
**この設問に対して、皆さんなら何と答えますか？**

かのエリック・エバンス氏も「**なぜこの２つなのか**」については述べていないようです。
他のフォロー本とかでも見かけないですね。なのでこれに対する答えを推測するなら**エンジニアリング**や**プログラミング言語**の基本から判断材料を集めてくる必要があります。

## あらゆるエンジニアリングの基本

「ユビキタス言語」と言うエバンス氏の造語を使うのをやめて「言葉の統一」と言う一般的な用語に置き換えれば、先の２つはドメイン駆動設計どころかソフトウェア設計の枠も外れて、全ての設計の基本中の基本になります。

そう、「言葉の統一」と「モデル駆動設計」は**あらゆるエンジニアリングの基本**です。
ソフトウェア開発の場合はプログラミング言語という言語をツールとして使うので
前者の比重が他分野に比べて大きいのでしょうが、根本は変わりません。

後ほどその辺りも合わせて深掘りしていきますが、
その前にプログラミング言語の基礎について述べておきます。

## ここからプログラミング言語は始まった

プログラムの3大要素の「**状態、制御、演算**」を知っている人は多いでしょう。
（まあ、私も記事で紹介しているし）
でもこれってCPUとかの動作原理、言い換えればハードウェア由来の要素なんですよね。ソフト屋としては「**プログラミング言語が言語である**所以である」純然たる「プログラミング言語の基本要素」も気になります。
言い換えれば「**マシン語とプログラミング言語の最初の違い**」って何でしょうか？

型？いえいえ。
答えは「**ラベル**」です。普通の言葉で言えば「**名前**」ですね。このラベルを加えることで、言語と言うより**装置の一部だったマシン語**は人が操るプログラミング言語に成りました。つまり**ラベルが存在しないプログラミング言語はありません**。
では、そのラベルの役割は何か？
それは名前に紐づいた**何かを思い起させる事**です。
いわゆる「**連想**」ってやつですね。

この「連想」と「論理構造（実処理）」の２つこそが**プログラミング言語の最も基礎的な要素**ってことになります。プログラミング言語には**フラクタル性**があるのでこの要素もプログラミングの**あらゆる箇所**で形を変えて顔を覗かせます。

「**連想配列**と**配列**」が代表例ですね。
他にも「関数変数と無名関数」とか、「クロージャ引数の名前アリと名前無し」とか、
この対比が適用できる要素はソフトウェアとその開発工程に偏在しています。

感が良い人はもうお分かりでしょうが
「ユビキタス言語とモデル駆動設計」も**設計過程**における「連想と論理構造」の発露です。

では、エバンスDDDの基本は「**プログラミング言語の２大要素**」から来ているのでしょうか？
もしそうなら「連想」についての深い記述があるはずなので、残念ながらおそらく違います。
青本の傾向から見ておそらくエバンス氏は**独自の経験則**として導き出したのでしょう。**先ほどの問いの答えは出てしまいましたね。**

だがしかし、私が**推したい**のは「**連想と論理構造**」です。

こっちだと以下のような**良いこと**があります。

- ソフトウェア独自の事象により深く言及できる。
- 各ラベルのネーミング基準を説明しやすい。
- 文単位の約束事に対する説明がしやすい。
- 論理構造に対する設計基準を定めやすい。
- **ドメイン駆動設計**の始まりが**プログラミング言語**の始まりと**同期**する。

個々のメリットは詳細の中で述べますが、注目すべきは「**始まりの同期**」です。
**極論**なのは間違い無いでしょうけど**浪漫**がありますよね？
だって**80年ぐらい前にはDDDしてた**可能性があるんですよ！


...さて、妄想はこれぐらいにして、そろそろ深掘りしましょうか？

# プログラミング言語とソフトウェア設計の基本を同期させる

ここからがようやく**本番**です。
ここでは「**連想と論理構造**」がソフトウェアの設計や実装、さらにはDDDと「どう関係しているのか」を述べます。

## 連想と言語
プログラミング言語に限らず、**全ての言語は常に**「連想」を伴います。
**単語**に限らず**慣用句**や**文**でも人が何らかの事象を思い浮かべることで**言語**はその**役割**を果たします。
この時に個々の受け手が**別々の事象**を思い浮かべたらコミュニケーションが成立しませんから
ソフトウェアに限らず複数の人が集まって作業する場合は「**言葉の統一**」は必須事項です。

ソフトウェア開発の場合は「人の言語」と「プログラミング言語」の２種類を同時に扱うので
この両者も可能な限り統合して同じ言葉を使うようにする必要があります。
じゃないと開発者自身が混乱しますから。

と、ここまでが「ユビキタス言語」とか「連想する内容を他人と合わせる」話でした。

だがしかし、日々プログラミングをしていて直面するのはもっと**根本的な問題**なんですよね。
そう、「そもそも連想できない」つまりは「**何書いてんのかサッパリわからん**」ってやつです。
これが**読み手**の知識不足や技術不足なら「学習してください」と言えるのですが、
実際のところ**書き手**の力不足が原因なことが多くて、しかも教材らしきものが出回っていないので「**良いソースをたくさん読め**」とか雑なアドバイスしかしてないのが現状です。
ただ、この方法だと数年単位の時間が必要ですし、そもそもそこまで**努力できる**人が**稀**なんですよね。
私もそんな面倒なことはイヤです。

と言うわけでもう少し詳しいアドバイスをしましょう。
個々の名前をつける際に、何となく思い浮かんだ言葉を翻訳するのではなく
「**連想の速度と精度の最大化**」というテーマに取り組んでみてください。
続けるのは大変でしょうが、確実に**コードの読みやすさ**が向上するはずです。


## 論理構造とモデリング
ソフトウェア設計に限らず**全ての設計**はモデリングという工程を通ります。
モデリングとは「形作ること」つまりは何らかの構造を作るってことです。
ソフトウェア開発ではその構造が**論理構造**になります。

では**論理構造って何でしょうか？**

一番**単純かつ難解**な**二値論理**から始まり、型や関数とかモナド、あるいはデザインパターン、ライブラリやフレームワークに至るまで、ソフトウェア開発で出てくる**実装**に関する**概念のほぼ全て**が論理構造です。
「モデル駆動設計」の「モデル」というのは「何らかの要件を満たすための論理構造」のことです。
粒度感的には**デザインパターン**が一番このモデルに近いですね。
つまり１つもしくは数個のデザインパターンに相当する論理構造を作りながら設計を進めるのがモデル駆動設計です。

「**何を当たり前のことを言っているんだ？**」と思うかもしれませんが
ソフトウェア業界だと設計者の専門や経験からちょっと外れると**応用が効かなくなって**実装は現場任せになることがよくあります。こうしたケースの多くは**実装段階で混乱**します。ソフトウェア業界では技術の流行の移り変わりが早いですが、それらを追いかかるだけでは設計に必要な知見は身につきません。

あらゆる設計は「理論」と「実装技術」の両方に基づいています。
モデルも同じくこの２つがベースです。そしてソフトウェアではモデルは論理構造でできています。

論理構造やモデルは実装技術ではありませんが、ほぼ実装技術に直結しています。
同様に論理構造は理論や思想や哲学ではありませんが、それらに裏打ちされています。

「モデル駆動設計」では**理論と実装技術**に裏打ちされた論理構造を**部品**として使って**モデルを構築**していくことで、先述のような混乱を起きにくくします。


## 言語構造と論理構造
プログラミング言語はラベルの他に**型**、**制御コード**、**値**といった要素で構成され、それらが組み合わさって**文**となって初めて**命令**や**宣言**として成立します。パーツが組み合わさって文になるのは自然言語と同じですが、自然言語と違って、CとかJavaとかSwiftといった汎用プログラミング言語は「言語構造」すなわち文法が「論理構造」とほぼ一致しています。
比較的わかり易いとされるPythonや、裏に沢山の論理構造を隠し持っているHaskellだってそれぞれの言語の論理構造と文法は一致しています。
このため**プログラミング言語**を使って**直接モデリングを行う**ことが可能です。
この特徴は一見すると便利なようですが３つほど問題を抱えています。

一つ目の問題は**冗長**で読みにくくなりやすいことです。
型、変数、スコープ等の宣言は論理構造としては必要ですが、関心ドメインからは外れており、これらが増えると設計に集中できなくなります。この問題に対しては型推論や「シュガー・シンタックス」と呼ばれる簡易記法などの仕組みで冗長な部分を省略することで読みやすくする工夫がなされています。

もう一つの問題は**言語が提供していない論理構造を構築するのが難しい**ことです。
これを解消するために他の言語へのインターフェースを提供したり、内部DSLを構築できるようにする工夫がなされています。
DSLとはDomain Specific Language の略で領域制限言語と訳されていますが、要は特定分野向で使われる論理構造を表現するための文法を持つプログラミング言語です。SQLとかHTMLとかYAMLなどが代表例ですね。jsonみたいに他の言語の一部だけを抜き出した変わり種もあります。

最後の問題は**自然言語の文法から遠い**ことです。
近年は深層学習を使った自然言語解析などの研究も進んで、自然言語とコンピュータとの距離は縮まっていますが、それはそれ。
実際にはプログラミング言語と自然言語の差異はほとんど減っていないし、それどころかライブラリやフレームワークでは言語構造でも用語でも自然言語と大きくかけ離れた実装が日々増産されています。そのせいで言語より**ライブラリの習得の方が難しい**ケースをそこそこ見かけたりします。

最後の問題は結構深刻ですね。
技術者の力量を図る試金石にもなっているので一概に否定できないのですが、せめて慣れたらサクサク爆速で書いたり読んだりできるように**文法も合わせて気を使って欲しい**ところです。プログラムで使う単語のほとんどは英語ベースなので前置詞や助動詞や過去形、複数形の使い方ぐらいは合わせるべきだし、メソッド（モナド）チェーンを使った一連の文などでは**句の分け方１つ**で読みやすさが大きく変わります。
でもって、そこを外したら、いくら頑張って論理構造を設計しても「**読みづらくて保守性が悪い**」という烙印を押されてしまいます。
特に理系学科の出身者は自然言語を操る訓練が足りていない（かつての自分もその典型でした）ことが多く「**中身はしっかりしてるけど読みにくい**」という勿体ない状況が頻発しがちなので要注意です。

ちなみにエバンス氏が提唱するユビキタス言語は青本を読む限りでは「IT版ピジン語 [^1]」とでも言うべき「話し言葉」であり、かつ、DDDが「設計」を対象にしていることから、「実装言語」についてはほとんど触れられていません。確かに「設計」は特定の実装言語には左右されませんが、言語がサポートしている「論理構造」とは無縁じゃないし、プログラミング言語もPythonのように「クレオール語[^2]」的な言語の方が読みやすい[^3]ようなので、そのうち時代が変わるんじゃないですかねぇ。

## DDDはどこから来て、どこにいくのか

「マシン語を人にわかり易くする」「そのために論理構造に名前をつけて言葉にする」というのがプログラミング言語の原点です。ソフトウェア設計もプログラミング言語を基にしている以上、これらから自由ではいられません。特に「言語の性質とモデリング」に着目しているドメイン駆動設計は最も原点に近い設計思想だと言えます。
ただし、エバンスDDDはオブジェクト指向を基にモデリングを行なっており、それより前の時代の構造化設計や旧い関数型プログラミングでDDDと呼べる設計ができていたのは未知数です。とはいえ旧いフローチャート図でもモデリングは可能ですし伝言ゲーム等の言葉の問題は普遍的なので、そこそこ旧い時代からDDD的な何かはあったことでしょう。
同様にモデリングのベースとなる論理構造が今後進化を遂げれば、DDDもまた進化していくのでしょうね。

# 結論
- それ！DDDの専売特許じゃないですから！（言語の統一とモデル駆動設計は全エンジニアリングの基本！）
- エバンス氏のDDDはプログラミング言語の問題には触れていないから、自分に言わせると物足りない。<br/>（連想と論理構造 推し）
- ドメイン駆動設計の起源はプログラミング言語と同じ！（浪漫）

[^1]: **ピジン語**: 文法を持たない原始言語。異なる言語圏の人同士が商取引などで使う片言の話し言葉で、統一された文法を持たない。
[^2]: **クレオール語**: 文法を持つ原始言語。ピジン語話者の子供達が話す言語で、一貫した文法が形成されてる。
[^3]: Pythonは他の言語ではコーディング規約として扱われる事項を文法に取り入れており、それが読みやすさにつながっているらしい。