T6-501多言語パラダイムによる実装手法に関するフォローアップ
TechEdの「T6-501 多言語パラダイムによる実装手法」に関して、フォローアップとしてお話した内容を記載します。説明した内容は、論点が3つあります。
- プログラミング言語と計算モデル
- 複数の言語を組合わせた具体例
- 分析・設計のおける考慮点(マルチパラダイムを抽出するために)
最初の「プログラミング言語と計算モデル」では、コンピューターで動作させるモデルとしてチューリングマシンやラムダ計算モデル、並列に特化したDAGやCSPなどのモデルが存在しており、近年のプログラミング言語はマルチパラダイム化しているが、中心となる計算モデルというものが間違いなく存在するということです。従って、汎用言語(GPL)が他の計算モデルへ対応するためにマルチパラダイム化したとしても、現時点では最適化などを考えると最適解には決して成り得ないという話をしました。この理由として、複数の言語が活発に使われているし、新しい言語も開発されていることを取り上げました。現実的に複数の言語を組合わせる時の問題点として、「人材が居ない」とか「新しいことを覚えたくない」とかを良く耳にします。ですが、この論点においては生産性などとのトレードオフで判断すべきだという説明をしました。その理由として、不可能ではないけど頑張れば出来るから頑張って1000行のコードを書いたとして、別の言語を使うと500行で済むことが良くあるからという話をしました。これは、別の言語を知っているかどうかであり、異なるパラダイムでは異なる問題解決アプローチがあるからです。だから、様々な言語を知ることは自分にとって有益になります。
次に具体例として、動的言語と関数型言語を取り上げました。動的言語では、オブジェクトの結合度を弱めるためにObjectコンテナーが、スクリプトでオブジェクトを生成する3種類の戦略をお見せしました。これ以外にも、検証ルールや構成パターンなどをデモでお見せしました。これらの理由は、オブジェクト同士の結合度を弱めることで、変更が起きる可能性をスクリプトなどへ隠ぺいすることで、保守容易性や変更容易性を向上することができます。
続いて、非同期パターンを組合わせた場合にプログラムが複雑化していくという説明をしました。この問題を解決するために、F#の非同期ワークフローが有益であり、同時実行などを考えた場合はアクターモデル(メッセージ エージェント)を使うと簡単になるというデモをお見せしました。さらに、デモの中ではWPFで作成したUIへイベントを通知するモデルを用意することで、非同期+リアクティブ プログラミングという組み合わせの重要性を説明しました。.NET Frameworkの非同期処理で、Begin系メソッドで呼ばれるコールバックメソッドは、Beginメソッドを呼び出したスレッドとは異なるスレッドで呼ばれます。このためコールバックメソッド内で、イベントを発生させるとコールバックメソッドが動作しているスレッドになってしまいます。このままだと、UIスレッドとは異なるためWPFではDispactherを使わなければならなくなり、この形式は良くありません。何故なら、イベントの利用者がDispactherを意識する必要があるからです。この問題を解決するには、同期コンテキストを使ってイベントを呼び出し側スレッドに同期させるのが良いリアクティブ プログラミングとなります。
最後に説明した分析・設計における考え方では、以下のような考え方をベースに説明をしました。
この中でご説明したこととして、現在のOOA&Dではプログラミング言語が持つ制約としてのクラスを抽出することに重きを置いており、ユーザーの目的を支援する本来のオブジェクトになっていないということです。このギャップを埋めるために、Agileの様々な手法が使われています。その例として、XPにおけるユーザーの参加と早期のフィードバックを踏まえた動くソフトウェアを素早くリリースするというプラクティスを取り上げました。この考え方からCoplienのDCIアーキテクチャに繋がっており、彼の考え方によればクラスのしての設計時点の振る舞い(Methodfull Role)と、オブジェクトが動作する場(コンテキスト)において異なる振る舞い(Methodless Role)が出てくるということです。従ってDCIでは、ユーザーのゴールを「ドメインオブジェクトに対する操作」ではなく「目的を達成するためのタスクフロー」に置いています。
一方、DDDの世界においてはEric Evansなどのその後の研究や実践した結果から、書籍としてのDDDに定義されていないことなどを学習していき、DDDを再定義しようとする動きに繋がっています。これらの動きが、DDD eXChange 2010の資料などから読み取ることができます。DDDの再定義から提唱されているのが、以下のような考え方です。
- Event Sourcing
- Process Integration
Event Sourcingでは、CQRS(Command Query Responsibility Segregation-コマンドとクエリーの分離)という考え方でオブジェクトの振る舞いを分離していきます(この考え方が、T1-502の萩原さんのセッションでも説明がありました)。また、DDDのビルディングブロックとして、Entities、Value Objects、Services、Domain Events(非同期イベント)、Aggregates、Modulesなどが定義されると再定義しています。これは、EvansなどのDDDの考え方をクラウドを含めたシステムに対応できるように考え方を洗練させていったことにより出てきたものと考えられます。このビルディングブロックやCQRSを組み合わせると、ドメインモデルにはコマンド系のメソッドしか残らなくなります。こうなると、今までのドメインモデルとは異なったものに変化していきます。
EvansのDDDの世界で重要なポイントと私が考えているのが、Bound ContextとContext Mapになります。モデル(オブジェクトと言い換えても良い)が意味を成す領域がBound Conetxtであり、これに関連するContextとの対応関係がContext Mapとなります。よって、このことはContextによってモデルの振る舞いが決定されることを意味します。このようなEvansなどの考えに気が付いた時に私が思い出したのが、Martin Fowlerの「Development of Further Patterns of Enterprise Application Architechure」になります。つまり何が言いたいかといえば、ドメインモデルを現在のシステム形態(Key-Valluesストレージなどのクラウド技術を含んだもの)へ対応させるにはどうしたら良いかという動きが、今まさに始まっているということです。
Evansのこのような考え方は実装により近いのではないかということを私は考えており、Coplienはもっと上流(別の言い方ではユーザーより)から考えているように私は感じています。これはどのような視点でシステムを見ているかによるものです。そして、もっと重要だと私が考えるのは、システムにおける共通性と可変性を識別し(ドメイン工学のFODAなど)、可変性をどのように実現していくかということです。それが、DCIアーキテクチャや再定義されつつあるDDDの前提になっていると私には思えます。
分析・設計論として、簡単な結論があるわけではありません。考えるべき事柄が多岐に渡っており、それらの要素に気が付くというのが本セッションの大きなテーマでもありました。このような雰囲気が参加者に伝えようと意図したのが、今回の私の発表になります。
PS.これらの考え方は、今回のセッション資料を作成するに当たって萩原さんと何度もディスカッションをして得られた気づきによるものです。これらのディスカッションは、TechEdの期間中も何度も行っており、その中でお話する内容が決まっていきました。これらの理由から、公開している資料には本エントリーで記載さしたようなキーワードが含まれいないのです。