2009年10月2日金曜日

ユビキタス言語と日本語

数ヶ月前から社内でDDD勉強会を実施していて、最近「ユビキタス言語(Ubiquitous Language)」まで来たんだけど、ここでやっぱり「日本語を使ったら1つの言語、モデルになるのか?」という疑問が出てきた。JavaEE勉強会でも同様の意見が(確かhirataraさんから)出てきていたものの、残りの部分に答えが書いてある可能性もあったので、その時点では「まぁ、用語の一覧みたいなのを作ってなんとかすればいいんじゃないの?」と流したものの、あらためて同じ問題に直面してみると、なかなかやっかいな問題だ。先に進む前に、この時点での自分なりの結論を書いておく。

DDDの世界観
まずは、DDDにおけるユビキタス言語やモデルの扱いについて簡単にまとめておく。
# 断るまでもないと思うけど、もちろん個人的な理解。

ユビキタス言語はドメインモデルに基づく言語であり、ドメイン専門家と開発者の双方が作り、双方が使う。これら2つは一体となっており、片方が変更されればもう一方も変更される。

ユビキタス言語が構成する世界−−言い換えれば、言語によって制限された物の見方−−がモデルであり、モデルは第一義的には概念上の存在である。わかりやすく言い換えると、モデルのマスターは頭の中に存在している、ってこと。これを文章やダイヤグラム、コードで表現することもできるけど、そうして表現されたものはすべてモデルの死体のようなもので、作った瞬間から古くなっていく。

モデルが頭の中にしかないのであればユビキタス言語も同様で、会話の中にあらわれるものこそが第一義的な「ユビキタス言語」になる。

僕たちはソフトウェアを開発したいので、モデルが頭の中にしかないってのはあまりうれしくない。最低でも(モデル表現としての)コードは必要になってくるけど、DDDではモデルを複数作らないのが原則だ。となると、コードの構造は頭の中のモデルを投影したものになり、コードはユビキタス言語で表現されることになる。

DDDの世界観は、こんな感じ。

で、問題は何よ
日本で開発する場合、顧客と開発者の会話はふつう日本語で行われる。よって、ユビキタス言語は日本語として構築されることになる。
一方、プログラミング言語は通常英語(というよりは英数字)がベースだ。日本語プログラミング言語も存在しているが、少なくとも業務システムではほとんど使われていない。最近の言語はたいていUnicodeをサポートしているので、識別子として日本語を使えばいいじゃん、と思うかもしれないが、言語が持つ標準的なコーディングスタイルから著しく逸脱するので、信じられないほど可読性が低下する。
# 一度Javaでやってみたことがあるが、正直2度と読みたくない。

どうするべき?
ここで取るべき道は2つ。
  1. コードは英語、その他は日本語
  2. コードはローマ字による日本語表現、その他も日本語
ここで、僕のような西洋かぶれは1番目の方法を選びたがるわけだけど、これはおそらく大きな誤りだ。
英語と日本語は、単に文法や単語が違うだけではなく、世界の見方自体が異なっているので、どうやってもうまく対応させられない部分が出てくる。それがわかっていればまだ良い方で、うまく対応させたと思っているものの、実際は完全に間違えていることだって少なくない。そうした無理な変換によって、実質的にはモデルが2つできてしまいかねない。
そもそも母国語だけ使っていても、単一のモデルを(言語、文章、コードにわたって)維持するのは非常に困難なので、基本的な道具立てに撹乱要因が入るのはできればご遠慮願いたい。

2番目は、おそらく現場で一般的に取られている方法だろう。コードを見ると頭が痛くなるような識別子が並ぶことになるのだが、無理に英語を使って混乱するよりはまだマシだろう。

言語学との関連
実際のところ、一番興味深いと感じたのは、Evansのユビキタス言語に関する考え方が、最近読んだ言語学の本での言語に対する態度とかなり近いという点。言語として会話を重視する、といった態度のことね。考えてみれば当たり前なんだけど、言語の中には文字がないものだって存在するし、何より頻繁に変わっていく(設計のためのユビキタス言語のような)言語に追随するには、話されている生きた言語を捕える必要がある。
にもかかわらず、自分も含めて、言語を「紙に書かれた文字や文章」や「文法書」、「辞書」である、と考える人が異常に多いということに気づいて愕然としてしまった。

2009/10/8追記:
勉強会でさらに話し、名詞の厳格な扱いのおかげで概念をより厳密な言語(プログラム言語)に落とし込みやすい英語と比べ、日本語では概念を明確にしづらい…といった話が。結局、ユビキタス言語は混成言語(ピジン語)のようなものにせざるを得ないのかもしれない。ただし、文法の混成はかなり限定的になりそうだけど。

2009年10月1日木曜日

コンテキストあれこれ

知り合いのu1hoshinoががんばってAP設計のノウハウをまとめはじめたようです。手始めはコンテキストですが、前半の概念を導入している部分でいろいろ消化不良感があったのでコメントに書こうと思ったのですが、長くなりそうだったのでこっちに書きます。脳内ダンプ的なものなので、特に結論はないです。

コンテキストって何
計算機の話に限定すれば、「コンテキスト」は「特定の計算における環境」だと言えます。ここで言う「環境」としては、広義には言語やランタイムを表すこともありますが、今回は(元記事の想定に基づいて)「変数と値のセット」に限定します。

特定の計算を構成する命令(ステートメント)を、何かしらの形(関数、プロシージャ、クラス…)でモジュール化することを考えた場合、計算に必要な入力値すべてを引数や戻り値で渡せば、環境は不要になります。実際、純粋関数型言語ではこのようにして計算を組み立てます。しかし、モジュール(の複数の命令)をまたがって同じ情報を繰り返し参照するなら、その情報はパラメータで渡すのではなく、環境として設定してどこからでも参照できるようにすることで、モジュール間の結びつきが煩雑化するのをある程度抑えられます。これが、コンテキストを利用する比較的大きな理由だと思います。

# 他方で、抽象化された「環境」を引数や戻り値として受け渡していくことで、副作用を排除しつつモジュールの煩雑化を防ぐ、モナドのようなアプローチもあります。

何故Webでコンテキストを作るのか?
Javaで標準的なWebインフラ(Servlet)には、組み込みでリクエスト・セッション・アプリケーションなどのコンテキストオブジェクトが存在しており、自由に利用できます。
これらのコンテキストにはServlet内から自由にアクセスできるため、まさに「特定のリクエスト実行における環境」になっており、Servlet内部に命令を書いている限り、これらがまさにコンテキストとして機能したはずです。
しかし現状では、レイヤパターンの適用によってリクエスト処理を複数モジュールに分割し、Webレイヤ以外では上記のコンテキストは使えないように設計するのが一般的になりました。これによって、ビジネスロジックと呼ばれる命令群が特定インフラへ依存することは少なくなったものの、コンテキストの喪失によって最初に設定した問題が発生することになりました。これを解決するために、Web非依存の独自コンテキストを再設計している、というのが元記事で言うところの「コンテキスト」が誕生した経緯です。

コンテキスト情報として何を設定する?
これは、計算の性質や、どのようにモジュール分割するかによって変わりそうです。また、リクエスト処理のコンテキスト設定がアプリケーションプログラム側で許可されていないケースも多く、基盤や(APじゃない)アーキテクチャが把握できる範囲となると、相当広範囲で共通的に使われるものに限られるケースが多くなります。結果的に、元記事でも書いてあるような
  • ユーザー情報
  • 日付
などが多くなるわけですね。
また、コンテキスト情報として設定するものの中で、レイヤ指針に反するような内容を設定した場合、不適切な依存関係が発生する可能性があるので注意する必要があります。ビジネスロジックをインフラから切り離すためのレイヤ化だったのに、コンテキストに端末IDやIPアドレスが設定されていると、ロジックがこれらに依存する可能性があります。単なるデータとして扱っているうちは良いですが、不用意にインフラに特化した「型」に依存してしまうと、物理モジュールの管理が面倒になるので、注意が必要です。

結局
結局、「コンテキスト」が何で、どうして必要なのかを自分の中でもう少し整理しておきたかったというわけでした。書いてみると当たり前というか、しょーもない話ですね。