エンジンの変遷
Fluxengine 代表の神原です。私がエンジンを作り始めたキッカケは、Delphi のカスタムコンポーネント開発でした。当初は、Grid など Visual Component を作っていたのですが、段々と開発の中心が Invisual Component 作りに移っていき、エンジンの形になっていきました。作っていたのは BI ツールで、セマフォを使って非同期にサーバから取得した Key Value 形式のデータをメモリ内で3次元化し、スライス・ダイス・ドリルダウン、あるいは、縦ソート・横ソート・グループソート・各列ソートなどを汎用的に処理するものでした。サーバ側はすべてストアドプロシジャとし、プロシジャ名や引数などメタデータを OCI や ODBC 経由で取得し、名前一致ルールで Visualコンポ ⇔ Invisualコンポ ⇔ StoredProcedure 間をデータバインドする仕組みとしました。
このエンジンを使って、数社の販売管理システムや仕入管理システムなどを構築し、後に更新系の仕組みを拡張し、各種マスタメンテナンスシステムにも導入していきました。
また、時代に応じて、Delphi Visual コンポLib ⇒ Taglib ⇒ JavaScript コンポLib ⇒ React.js と、フロント側の利用技術を変えていきました。ただ、フロント側は技術は変わってもコンポーネント指向やデータバインドの考え方は昔も今も同じです。
サーバ側も、ストアドプロシジャ ⇒ マイクロサービスの REST API と変遷していくのですが、フロント側の様に「単に利用技術を変えるだけ」とはいきませんでした。
エージェント指向との出会い
1990年代、特に1994年は、Delphi そして RAD(Rapid Application Development)と出会い、上述の初期のエンジン開発にのめり込んでいました。私にとって、Anders Hejlsberg と James Martin は憧れの人であり先生でした。
2000年代になって、それまでやってきたエンジン開発やオブジェクト指向設計能力を買われ、複雑系(complex system)のシミュレーションシステムを手掛けるようになりました。当時、音波伝搬を計算する様な単体の物理演算プログラムは既に存在したのですが、それら物理演算が現実世界で偶然に重なり合ったときの創発をシミュレーションする分野はまだこれからという状況でした。それで、どういうソリューションを提案するか思い悩んでいたときに、エージェント指向と出会いました。
エージェントは、「目的指向性」「即応性」「社交性」を持たなければならないのですが、社交性は、当時 FIPA が標準化していた ACL(Agent Communication Language) をベースとし、目的指向性はプロダクションシステムの考えをベースに、ルールエンジンをスクラッチで設計しました。問題は、即応性でした。強化学習や遺伝的アルゴリズムなど、適用できるものを求めて色々と研究したのですが、シミュレータとしての目的に合致するものではなく、結局は単純にランダムに振る舞いを決めてモンテカルロで回す設計としました。
このプロジェクトはとても楽しいものでしたが、同時に非常に苦しくもあり、成果も出せずに終わりました。しかし、このとき引いた設計や経験したことが、後のドメイン駆動エンジン開発に大きなヒントを与えてくれることになります。
ワークフロー
次に手がけたのは、エンタープライズ向けのワークフローシステムです。フロント側は、かつて Delphi で作っていたビジュアルコンポを Web 技術で作り直すことにしました。当時、2006年ごろは、まだ React.js などは存在していませんでしたので、スクラッチでコンポーネント指向の JavaScript ライブラリを設計しました。こだわったのは、Windowsアプリケーションと遜色ない UI をブラウザで実現することです。JSX ではなく HTML の拡張属性を使って、ビジュアルコンポ・データソースの関係性や配置・階層を定義し、SPA(Single Page Application) として動作する様にしました。
サーバ側は SOA の考え方を取り入れ、機能を「フロー制御」「組織検索」など幾つかのサービスに分解しました。サービス呼び出し部分は、フロント側で定義したデータソース間の関係性を読み取り、各サービスを自動オーケストレーションするエンジンを構築しました。また、ワークフローの要であるフロー制御部分のエンジン設計にも、かなり工夫をこらしています。当時存在した BPM 系の仕組みは、どれもワークフローのステップをノードとするグラフ構造をベースとしていましたが、差し戻しなどの表現がグラフ構造では複雑になりがちです。定義が複雑になると、設定するのも大変になってしまうので、いかに単純でシンプルな構造でフローを表現するかが鍵となる訳ですが、エンタープライズ向けの長く複雑なフローを定義できる必要もあるため、エンジンのモデリングに苦労しました。
初期のエンジンと比べると、ビジュアルコンポ部分は利用技術が Delphi ⇒ JavaScript に変わっただけですが、データソースの依存関係と評価順序を制御するデータフローエンジンが、フロント・サーバにまたがって形を成してきています。また、ストアドプロシジャは SOA サービスに置き換わりました。このワークフローシステムは、現在では大手企業を中心に数百社に導入されるほど、利用が拡大しています。
ドメイン駆動エンジン
James Martin の RAD本に感銘を受けて以来、エンジン開発と並行して、お客さま業務のコアドメインをクラス図やシーケンス図などモデルで表現する方法を模索していたのですが、数社のお客さまの反応から「状態マシン図」が商品やサービスのモデル表現に適していることが分かりました。ただし、状態マシン図だけではコアドメインを表現し切れません。どう補うかを長い間考え続けた結果、あるとき、エージェント指向の設計と融合させることを思いつきました。
その頃、ソフトウエアエンジニアリング関連の本を読み漁っていて、SPLE(Software Product Line Engineering) という本に出会いました。また、PoEAA(Patterns of Enterprise Application Architecture) を読んで、ヘキサゴナルアーキテクチャも知りました。
そして、ヘキサゴナルアーキテクチャの構造をエージェントのモジュール構造になぞらえること、中心のアプリケーション部分をモデルで表現すること、モデルは「状態マシン図」「ルール」「イベント」「データソース」「データフロー」で記述すること、モデル記述は専用のDSLを用いることなど、エンジン構想を固めていきました。
エンジン設計が概ね固まったころ、エリック・エヴァンスのドメイン駆動設計を読み、考え方や方向性は同じだなと感じました。アプリケーションは「ドメイン」、状態モデルは「エンティティ」、データソースは「バリューオブジェクト」、ルールは「サービス」とマッピングすることができます。そして、エフェクタは CQRS(Command Query Responsibility Segregation) の「コマンド」、クエリーは「クエリー」と同じ役割です。そこで、このエンジンをドメイン駆動エンジンと呼ぶこととしました。このエンジンは、約3000万人が毎日利用するシステムの中核として採用され、現在も安定稼働しています。
絵では表現できていませんが、DSLは商品系列によって可変点を動的に切り替えられる様に設計しています。これは、SPLE の考え方を取り込んだものです。DDD や SPLE を具現化するエンジンにより、保守コストの削減や変更開発の期間短縮に効果があることも実証されています。
Fluxengine
私達は、これからも最高を求めて、Flux(変化し続ける)Engine(エンジン)を開発して参ります。
どうぞ、よろしくお願い致します。
0コメント