📚

DDDとロラン・バルト

2022/01/12に公開

昨年(2021年)12/16に増田亨さん主催のイベント「エヴァンス本のススメ」に参加した際、エヴァンス本の読み方と絡めてロラン・バルトの「エクリチュール」概念を紹介したのですが、あまりに唐突でちょっと喋っただけでは伝わらなかったろうなと思うので改めて記事にまとめたいと思います。

https://modeling-how-to-learn.connpass.com/event/229932/

ここではタイトルに「DDDと…」としていますが、本質的にはエヴァンス本や他の技術書籍に限らず、より広くプログラミングやソフトウェアの書き方とロラン・バルトの『零度のエクリチュール』についての話です。

TL;DR

  • 技術書やプログラミングを、言語、プログラミングスタイル、そして指導的設計思想(=エクリチュール)の3つのレイヤーに意識しながら読んでみましょう。
  • エヴァンス本のDDDでは、Smalltalk的なメッセージパッシングによるオブジェクト指向が指導的設計思想として背景にあります。
  • 是非はともかく、そうした設計思想を前提として書かれた本だと意識しながら読むとエヴァンス本も多少読みやすくなるのではないでしょうか。

ラング・スティル・エクリチュール

ロラン・バルトは、二十世紀に記号論・文芸批評の分野で活躍したフランスの思想家です。記号論とは、二十世紀初めの新しい言語学に基づいて言語によるコミュニケーションや文章をその「記号自体」と「記号が意味するもの」に厳密に分割して分析していく学問で、同時期に流行した構造主義という思想や新しい文芸批評の基礎となった考え方です。

バルトは『零度のエクリチュール』という本で、記号論に基づいて文学をラング、スティル、エクリチュールという3つのレイヤーに分けて読んだり批評したりする新しい手法を提唱しました。

※ プログラミングの話をしているので、ぜひプログラミングに置き換えて考えてみてください。

ラング(言語)

日本語とかフランス語といった言語そのものやその文法規則。言語活動をする上で皆が共有している基盤体系です。

プログラミングで言えば、Java、JavaScript、Python、Goといったプログラミング言語そのもの、コンパイラが受け付けるその文法や構文に相当します。

スティル(文体)

各作家の個性的な文体。夏目漱石、谷崎潤一郎、大江健三郎、村上春樹など、それぞれの特徴的な文章の書き方を想像してみてください。バルト以前の古い文芸批評では、このレベルの指摘に留まっていることが多かったようです。

プログラミングでも、インデントの仕方に始まり、早期リターンを使うかどうかなど、どういうスタイルでプログラミングを書くかに関して、プログラマー個々人の個性があります。『Effective Java』とかケント・ベックの『実装パターン』のような技術書は、主にこのレベルのコーディング作法に関する本かなと思います。

エクリチュール(なぜ書くか、何を目指して書くか)

単なる文体を超えたところにある、作家が文学とどう接しているかという本質的なアプローチの違い。単なる書き方の良し悪しを超えた、深い文芸批評をするにはこのレベルの違いに意識的になる必要があります。

いわゆる文学の「〜主義」みたいなものに近いですが、作家が意識的に選び取る「〜主義」と違い、言語学・記号論的観点から、ラングやスティルでは掬い取れない作家が意識・無意識的に向き合っている文学作品への姿勢や作家としてのあり方、みたいなもののようです。(記号論から生まれた構造主義が、社会の無意識的な仕組みをあぶり出す思想だったことを思い浮かべると理解しやすいかもしれません。)

プログラミングとエクリチュール

このエクリチュールがどうプログラミングと関係するか、何がプログラミングのエクリチュールと言えるかを考えると、ぱっと思いつくのは「オブジェクト指向」とか「関数型」といったプログラミング方法論でしょう。

しかし、最近ではScalaに始まりほとんどのプログラミング言語がオブジェクト指向と関数型の両方を取り入れていて、単にこの言語を使っているからオブジェクト指向でやっている、とは言えません。純粋関数型のHaskellですら、IOモナドを多用しているとシステム全体としては最終的に副作用を前提とした設計になってしまっている、と言えなくもありません(ここは識者からツッコミがあるかも知れませんが)。

要するに、プログラミングにおいても表層的にオブジェクト指向だからとか関数型でやってるから、と言っていても、実はシステム設計全体をガイドする思想としては全然オブジェクト指向になってない、関数型になってない、といったことは多々ある訳です。

プログラミングに「エクリチュール」的な見方を持ち込むとすると、同じオブジェクト指向でももっと設計思想の深いところの、Smalltalk的な「メッセージパッシング」に基づく設計とか、インターフェースの事前・事後条件を重視した「契約による設計」に基づく設計とか、そういったところで、技術書なりプログラムなりが何を重視し、信奉しているかに意識的になることだと思います。

究極的には、プログラミングのエクリチュールとは、どんなプログラミングによってそのソフトウェア(の実行)を実現したいか、ということになります。アーキテクチャとも似ていますが、もっとプログラムの隅々まで行き渡った設計思想というか向き合い方のようなイメージです。

「エクリチュール」についての注意点

「エクリチュール」という言葉は、色々な思想家・哲学者が様々な意味を持たせて使っている言葉です。もともとフランス語の"écriture"は「書くこと」、英語の"writing"程度の意味で、難しそうに聞こえますが単なる一般的な言葉です。

https://ja.wikipedia.org/wiki/エクリチュール_(哲学)

エクリチュールは、話し言葉に対して、書き言葉の特質に注目したときに用いられるタームである。したがって、その思想家の数だけ、その意義が存在すると言っても過言ではないため、留意が必要である。

ここではロラン・バルト『零度のエクリチュール』における「エクリチュール」の意味に限定して使っています。もっと哲学的な「エクリチュール」の概念もありますが、それらをプログラミングに持ち込んでも議論が発散するだけであまり意味がないと思うからです。

DDDのエクリチュール

本題ですが、ではDDDとくにエヴァンス本は、どんな技術的なエクリチュールに基づいて書かれているのでしょうか。

これだ、と明確に書籍に書かれている訳ではないですが、私が書籍を読んだりエヴァンス本の生まれた背景や著者の交流関係を見る限り、エヴァンス本ではSmalltalk的なメッセージパッシングによるオブジェクト指向が、その技術的なエクリチュールとしてあると思われます。

エヴァンス本の系譜

エヴァンス本は、それ以前にマーティン・ファウラーが『エンタープライズアプリケーションアーキテクチャパターン』(通称PofEAA)を書き、その中でドメインロジックのパターンとして紹介されたドメインモデルパターンを受けて出てきた、という時系列的背景があります。

そのファウラーは90年代にSmalltalkを使ったいわゆるC3プロジェクトなどでXPやJUnitを作ったケント・ベックと一緒に仕事をしてきた人で、ファウラーやベックはSmalltalk的なメッセージパッシングのオブジェクト指向を体現しているような人たちです。

実際、ベックがGoFデザインパターン著者の1人エリック・ガンマと開発したJUnit 3のソースコードを読むと、メッセージパッシングのオブジェクト指向の教科書のような作りになっています。

https://github.com/stefanbirkner/junit3

GoFデザインパターンも、MediatorパターンやVisitorパターンのように、メッセージパッシングに基づかなければ出てこないようなパターンがいくつもあります。

メッセージパッシングによるオブジェクト指向

メッセージパッシングによるオブジェクト指向って何なの、ということですが、Smalltalkを見てみると分かりやすいです。純粋オブジェクト指向言語とも言われるSmalltalkでは、すべてをオブジェクト間のメソッドコールで実現します。if ... else ...みたいな基本的な制御構文も言語にはありません。

x > 0
    ifTrue: [...]
    ifElse: [...].

このコードでは、x > 0というオブジェクトにifTrueifElseというメソッドコール(=メッセージパッシング)をして条件分岐を実現しています。

こうした言語を使って良い設計を突き詰めるとどうなるかというと、複数オブジェクトの組み合わせによる条件分岐やコレクションへのループ処理は、switch文やforループのように手続き的でなく、クラスの種類とオブジェクト間のメッセージパッシングで実現しよう、となる訳です。

この延長上に、私の好きなダブルディスパッチのようなテクニックが生まれます。ダブルディスパッチとは、要するに複数オブジェクトの組み合わせによる場合分けを、ifswitchのネストを排除して、代わりに2つのオブジェクト間でメッセージのドッジボールを1往復することで実現するものです。メッセージを1往復させることで、片道ではポリモーフィズムによって誰が誰に投げたか分からない処理でも、最終的にメッセージが戻ってきた段階で確定できます。

https://ja.wikipedia.org/wiki/ダブルディスパッチ

Visitorパターンなどは、言ってしまえばこのダブルディスパッチを単にツリー構造のオブジェクトに適用しただけです。

(メッセージパッシング的な)オブジェクト指向の古典などで、なるべくif文やswitch文を減らしてクラスで表現しよう、と書いてあるのは、要するにこういうコードを良いコードとして促したいからです。

つまり、究極的には、メッセージパッシングのオブジェクト指向では、複雑なビジネスロジックをクラスの種類と、クラス間の関連(=メッセージパッシング)で表現しようという設計思想にたどり着きます。

増田亨さんがDDDの解説をするときに度々「名前(クラス)がロジックの置き場所を導く」と説明されていますが、これも私はメッセージパッシングのオブジェクト指向に沿った考え方だと理解しています。

https://www.slideshare.net/masuda220/ss-62386442

ドメインモデルは再利用性が高いのか

少し脱線しますが、PofEAAやエヴァンス本が出版された当時(2000年代中頃)、ドメインモデルパターンやDDDの受容を巡って技術者の間で「本当に純粋なOOやドメインモデルが良いパターンなのか」が熱く議論されていた記憶があります。特に「ドメインモデルはコードの再利用性を高めるか否か」が大きな焦点でした。当時、Java EE勉強会が主催したDDD読書会でもこの争点がよく議論されていました。

https://www.wikihouse.com/withoutEJB/index.php?DDD

DDD推進派はドメインモデルはコードの再利用性を高めると主張していて、逆に懐疑派はそれに否定的でトランザクションスクリプトでも再利用性の高いコードは書けると主張していました。

現在のように、こうした議論をすっ飛ばしてDDDが当たり前のように受け入れられているのを見ると、隔世の感があります。DDD受容の観点からは、本当にいい時代になったなと思います。

私自身は、以前からドメインモデルはコードの再利用性も高めると思っていますが、それは正直どちらでも良くて、むしろ増田さんが説くように自然と「名前(クラス)がロジックの置き場所を導く」ことがDDDの最も重要なメリットだと思っています。

私自身の経験として、トランザクションスクリプトでやるとよっぽど規律をもってきれいな設計を維持していかないと、システムが大きくなるにつれてロジックの置き場所を考えるのに苦労するようになります。ドメインモデルだと、どんなにシステムが複雑化してもそれはビジネスロジックが本来持っている複雑さ以上にはぐちゃぐちゃにはなりません。

おわりに

冒頭の「エヴァンス本のススメ」イベントに参加していたときに思っていたのは、今も昔もエヴァンス本に挫折する「DDD難民」に溢れてはいるけど、今と昔とでは難民化するポイントが少し違うのではないか、ということです。

昔のDDD難民はまだ邦訳がなく、純粋にあの防弾仕様の分厚い洋書を読解するのに挫折している人が多かったように思います。PofEAAやドメインモデルの考え方などの、DDDを理解する上でのコンテキストはよく共有されていました。逆に今のDDD難民は、邦訳は手に入るので英語の苦労はないものの、20年前のコンテキストから切り離されて降って湧いた難読性の教典を理解するのに四苦八苦しているのではと思いました。

なので、20年前からDDD界隈でエンジニアをやってる人ならよく知ってるようなネタも、これからプログラミングをやる若い人向けに少し丁寧に書いてみました。

ちなみに、本記事主題のプログラミングとエクリチュールの考え方は、自分の中で長年考えてきたアイデアですが、文章にして公開したのはこれがたぶん初めてです。

Discussion