DDDの読書記録(第1章、知識のかみ砕き)

引き続き、DDDの読書記録です。あまり詳しく書きすぎるとネタバレになって本が売れなくなってしまうといけないので、読んでいて特に気になったポイントにしぼって書いていこうと思います。

第1章とびら(PCBエンジニアとの会話、P7)

第1章の最初の部分でプログラマーである著者がプリント基盤設計のエンジニアとの会話と通して徐々にドメインの知識を吸収・咀嚼しながら、ドメインモデルを構築していくストーリーが語られています。

数年前、私はプリント基板(PCB: Printed-Circuit Board)設計用の専門ソフトウェアツールを設計することになった。しかし、1つ問題があった。私は電子機器について何も知らなかったのだ。もちろん、PCB設計者から話は聞けたが、彼らの話にはものの3分で頭がクラクラしてくるのが常だった。このソフトウェアを作成するのに十分なくらい電子機器について理解するには、どうすればよいのだろう?納期が来る前に電子技術者になることなど、できるはずもないのだ!

エヴァンス氏はなぜこのストーリーを最初に語ることにしたのでしょうか。一般的にIT技術というとネットショップやソーシャルネットワーク、ネットゲームのような華々しいWebサービス系のドメインを思い浮かべる人も多いと思います。もちろん、こういったネット業界はIT技術によって初めて可能になった新しいビジネスなのですが、逆に言うとそういうドメインは最初からITを中心にして物事が都合良く定められているという事実もあると思います。たとえば、ネットワークの掲示板であれば、基本的にはRESTfulという考え方でWeb上に存在する情報(リソース)のCRUD処理を実現しさえすればよいので少なくともIT技術者にとって概念上は非常に簡単に問題を理解することができます。
しかし、一般的にソフトウェアが使われている多くの業務ドメインは、最初からITのことを考慮して業務が構築されているわけではもちろんなく、それぞれの業務ごとに研究されたり長年の経験が蓄積された固有の知識が複雑に絡み合って存在しています。そういった複雑さはどのような業種にも必ず存在しているのですが、複雑なドメインに対するわかりやすい例としてPCB設計の例を出してきたのだと思います。
このストーリーを読んでちょっと興味深かったのは、ドメインエキスパートであるPCBエンジニアもアマチュアプログラマーであるということが想定されることです。実際、後の3章でもう少し具体的に出てくるのですが、自分でテキストファイルを加工するようなスクリプトのようなものを独自に作ってメンテナンスできるスキルがあるようです。ですから、ソフトウェアの専門家としてのエヴァンス氏の役割としては、当然そういった単に機能をプログラミングに落とし込むといったアマチュアレベルのスキルよりもずっと上のスキルレベルが期待されているということになりますね。当然、オブジェクト指向設計などということはあたり前のようにできなくてはプロとして話にならないということです。日本だと、逆に単純なスクリプトすら作れない「プロ」のコンサル、SE、プログラマーも大勢いるのではないかと思います。
ちょっとこの章の主題とは異なるのですが、このストーリーを読んで私がまず素直に感じたことは、このようにプログラマーという職業に対するプロフェッショナル意識の高さですね。ドメインエキスパートであるPCBエンジニアとプログラマーであるエヴァンス氏の間に特に身分の上下関係ということはなく、お互いがそれぞれの領域の専門家として能力をいかんなく発揮している、そんな光景が頭に浮かんできます。日本の業界だと言葉上はビジネスパートナー(BP、協力会社)と呼ばれますが、実質プログラマー(PG?)は下請け以下の環境や立場で働かされるということが一般的ですので。このストーリーを読んでアメリカにおけるプログラマーの仕事に羨望を抱くとともに、日本でDDDを実践するための様々なハードルを感じざるを得ないところがありました。
それはさておき、このストーリーの中で最初は曖昧だった知識が徐々にかみ砕かれていき、有用なドメインモデルに落とし込まれていきます。特に印象に残ったポイントは以下の部分ですね。

最初は曖昧な用語が徐々に正確になる

最初のモデルでは、具体的な例としてチップがネットによって配線されながら、シグナルを送信している図(図1.2)が書かれています。おそらく、具体的なプリント基板の例やドメインエキスパートとの会話を通して、これが最初にエヴァンス氏が直感的に考えたモデルなのでしょう。でもその直後の会話で

といったことが判明し、モデルが訂正されていきます。

ドメインエキスパートの言っていることが曖昧なこともある

お客様は神様とは言われますが、ドメインエキスパートは実際には神様ではなく、言っていることが曖昧だったりぶれたりするのは当然です。ソフトウェアのプロであるプログラマーとしては、そういった曖昧性に惑わされることなく適切なモデルを構築する支援をできなくてはいけません。8ページの下の部分で突然、「レフデス」という言葉をドメインエキスパートが使いだしたのですが、それは結局コンポーネントインスタンスと同義であるということが判明しています。(ドメインエキスパート2の方は、前の部分で「「ネット」を表している四角がコンポーネントインスタンスとそっくりですね。」と言ってみたり、ちょっとぼけキャラを演じているところがあります。)

最初は重要だと思った概念を切り捨てることもある(モデルの蒸留)

11ページ目で「それではトポロジーはどこで登場するのですか」というエヴァンス氏の質問に対して、「プローブシミュレーションでは使用しません。」というオチになっているのですが、このように議論を進めていくと本来ドメインの知識としては重要なものであっても、ソフトウェアを作る上では無関係な概念も登場してくるということですね。「では、ここは省いていいですね?その機能を取り上げる時に再考しましょう。」と言ってバッサリと切り捨てています。この辺りがYAGNIというか、XP的な発想であり、将来必要だからと無駄な設計を行わないというアジャイルの精神がDDDの基本思想に反映されているのだと感じました。

知識のかみ砕き(P14)

このセクションで特に印象的な部分は以下のとおりですね。

旧来のウォーターフォール手法では、ビジネスエキスパートがアナリシストに話をして、アナリシストがかみ砕き、抽象化して、その結果をソフトウェア作成者であるプログラマに伝える。このアプローチがうまくいかないのは、フィードバックが完全に欠けているからだ。アナリシストはモデルを作成する全責任を負っているが、基になるのはビジネスエキスパートから得た情報だけだ。プログラマから学んだり、ソフトウェアの初期バージョンを体験したりする機会は全くない。知識は一方向に少しずつ流れるだけで、蓄積されないのである。

やはり、DDDの前提としてフィードバックが得られるアジャイル開発というのがあるといって間違いありません。少なくともイテレーティブな開発プロセスをとる必要があります。特に、ビジネスの人とプログラマーが対等な関係としてモデルを発展させるというプロセスにする必要があります。上流、下流といった封建時代の身分制度は絶対に撤廃されなくてはなりません。
時として、言葉上だけはアジャイルという言葉を採用しながら、実体は

  • 設計をしない
  • いつまでも仕様を決めない
  • PGの単価を切り下げる

といった都合のよい表面的な部分のみつまみ食いしつつ、実際はロースキルのPGを大量に採用して結局スパゲッティコードを量産するといった恐ろしい話も時々耳にします。アジャイル開発を成功させるためにはまず、この身分制度の問題を先にどうにかする必要があると思いますね。

プログラマが習慣的にリファクタリングを実行すれば、ソフトウェアを、継続的に拡張できる程度にはクリーンな状態に保てる。だが、プログラマドメインに興味を持っていなければ、プログラマはアプリケーションが何をすべきかだけ調べ、その背後にある原理には注意を払わない。そうしたやり方でも使えるソフトウェアを構築することはできるが、そういうプロジェクトは、既存機能の必然的な帰結として強力な新機能が現れるという段階には、決して到達することがない。

これは私自身も多いに反省すべきところです。私の経験上、ある程度大規模なプロジェクトだとフレームワークチームというのに属してしまうこともありますが、フレームワークやコードのきれいさなど純粋に技術的なところのみに意識を向けてしまいがちな傾向があります。ドメインエキスパート(少なくとも業務系SE)とプログラマーがもっと積極的にコミュニケーションするべきでしょう。この点Excel方眼紙に象徴される、大量の仕様書のたぐいもある意味ではコミュニケーションの阻害要因になっていますね。基本的に仕様書によほどの問題が無い限り、仕様書通りにプログラムを作成すればよいと考えてしまうので。結局そういう態度だと、仕様書通りのプログラムは作れても、将来的に新しい機能を組み込んでプログラムを発展させるといった方向に決してならないのです。逆に、文字の大きさがどうのこうのといった重箱の隅的な部分の品質に必要以上に工数をかけてしまうといったことになってしまいがちです。*1

継続的学習(P16)

ソフトウェアを書き始める時、我々は対象を十分に理解しているわけではない。

これはまったくその通りですね。使用するツールやフレームワークといった技術的なスキルを学習によって向上させるということは最低限当然として、本当に有用なドメインモデルを構築するためには、業務ドメインに対する知識を継続的に学習する必要があります。

こうして自ら学んだチームメンバは、最も重要な領域を含む開発作業に集中するにあたって、メンバの中で信頼できるコアとなる。このコアチームの頭の中に知識が蓄積されることで、彼らは知識をよりうまくかみ砕けるようになる。

これも、プログラマーを交換可能なリソースとしてしか考えていないSIerのモデルではなかなか実現が難しいところですが、とにかく、業務のコアとなる部分だけでもこうしたスターチームが構成できたらすばらしいことですね。
なお、結局、最終的にプローブシミュレーションの開発は中止になってしまったそうですが、ドメインの知識がチームで共有され、新しい目標が明確になったのは大きな収穫だったとしています。

知識豊富な設計(P17)

これは最初に上流のモデルを作ってウォーターフォールで開発するようなケースでよく見られるアンチパターンですが、学習プロセスの初期段階で得られた洗練されていないモデル(あるいは必要以上に複雑な、不純物の混在した蒸留が不十分なモデル)は、プログラムを作成する上であまり有用なものでないと思います。
このセクションでは貨物(cargo)の輸送アプリケーションにおける記帳登録(booking)処理で使用するドメインモデルの例が出てきます。翻訳書ではcargo bookingが貨物予約として訳出されていますが、予約するのは貨物ではなく、貨物を運ぶ輸送手段の方なので、一般的な物流配送システムにおける「集荷」の概念に近いと思った方が理解しやすいと思われます。*2
もともとの初期のナイーブなモデルだと単に航海*3が複数の貨物を含んでいるといった、直感的に分かりやすいモデルになっているのですが、最終的なモデルではオーバーブッキングポリシーというストラテジークラスが抽出されています。これはStrategyパターンの例ですが、こういったクラスを発見して抽出するといったところはまさに、業務知識とプログラミング知識の融合のなせる技かと思いますね。*4

深いモデル(P20)

役立つモデルがすぐに見つかる表層にあることはめったにない。

「表層」というメタファーで語られていますが、これは金やダイアモンドを発見するのと同じで、掘り下げないと有用なモデルは発見できないということが言いたいのでしょうか。
この節では貨物輸送システムで最初はがんばって貨物や輸送日程のモデルを詳細に記述するモデルを作ったのだけど、問題の本質は実は別の所にあることがわかったというエピソードを紹介しています。

結局、何ヶ月も知識をかみ砕いた後で我々が気づいたのは、貨物の取り扱い、すなわち、物理的な荷積みや荷下ろしや、ある場所から別の場所への移動などは、ほとんど下請け会社や社内の業務担当者によって行われているということだった。輸送業のエキスパートから見れば、関係者の間で連続して責任が移動するということだったのだ。

輸送業に対する見方がこうして深まったことにより、輸送日程オブジェクトが削除されることこそなかったが、モデルは抜本的に変化した。輸送に関する我々の考え方は、コンテナをある場所から別の場所へ動かすことから、貨物に対する責任を、ある当事者から別の当事者へ移動することに変わった。

エヴァンス氏ほどの一流モデラープログラマーであっても、最初から正しい答えを見抜くことはできない、間違いを修正しながら、徐々に正解にようやくたどり着くといったあたりがエンジニアリングの神髄を見ているようで、実にすばらしいことだと思いました。

*1:日本のSI業界でこそ、専門の技術者の必要性がもっと見直されるべきではないのか? - 達人プログラマーを目指して

*2:bookingもreservationもともに予約と訳されますがちょっと微妙なニュアンスの違いもあるようです。本来bookは帳簿に登記すること。reservationは物や場所を確保して保持することですね。http://oshiete.goo.ne.jp/qa/2559721.html

*3:voyageを航海と訳するのも難しいですが、このドメインでは多少違和感を感じるところです。海上輸送くらいの意味ですかね。一般にこういう場合に航海と呼ばれるのでしょうか?

*4:Strategyパターンについては、以下でも説明しています。ドラゴンボールで学ぶオブジェクト指向 改(第弐話) - 達人プログラマーを目指して