2012年3月30日金曜日

DCI (Data Context Interaction)

3月19日(月)に要求開発アライアンスのセッション『Object-Functional Analysis and Design: 次世代モデリングパラダイムへの道標』を行いましたが、説明を端折ったところを中心にスライドの回顧をしています。

今回は「Data Context Interaction (DCI)」として用意した以下のスライドを説明します。

オブジェクト・モデリングの問題点の一つに、ユースケースからドメイン・オブジェクトへ真面目に責務の分散配備をしていくと、ドメイン・オブジェクトの実現が非常に重たくなってしまうという問題があります。

ドメイン・モデルそのものに由来するドメイン・ロジックをドメイン・オブジェクトで実現するのは、本来のオブジェクト指向の趣旨にも則っており問題ありません。

論点となるのはユースケース由来のアプリケーション・ロジック。このアプリケーション・ロジックを、(1)どのようにして適切な責務に分解して、(2)どのオブジェクトに分散配備していくのか、というのがオブジェクト・モデリングのホットスポットで、オブジェクト・モデリング手法を比較する上でのポイントとなるところです。

大きく、ドメイン・オブジェクトに配備していく派と、アプリケーション・ロジックを別オブジェクトで実現する派に分かれますが、理論的な主流派は前者、実際の開発者は後者を選ぶというねじれ状態になっています。

それはともかく、責務をドメイン・オブジェクトのみに配備していくと、システムを取り巻く文脈ごとのユースケースで必要な責務を集積した、巨大な責務の集りをドメイン・オブジェクトがまとめて実現することになり、(1)太ったドメイン・オブジェクトになってしまうという問題が出てきます。これに加えて、(2)色々なユースケースの断片が分散配備されることは、モジュール化、疎結合、高凝集という観点からも問題です。また、(3)モデルのライフサイクルの違いの扱いも論点の一つです。(3a)比較的安定しているデータモデル、(3b)比較的ライフサイクルの短いアプリケーション・ロジック、(3c)比較的高頻度に更新されるUIロジックを同じモジュールに配備すると、(3a)のUIや(3b)のアプリケーション・ロジックに引きずられ(3c)のデータモデル(を扱う処理部)にも影響が出てしまいます。

(1)は集中することの問題、(2)は分散することの問題、(3)は集中することの問題なので、それぞれ相反する事象であり、全てを一度に満足することは困難です。程よく集中して、程よく分散するバランス点を見出し、プログラミング言語での自然な実装手法を確立していく必要があります。

この問題に対する解として一時期AOPが注目されましたが、あまりうまくいっていないようです。柔軟すぎるメカニズムは、プログラムの安全性という意味で問題がありそうです。静的型付けの枠組み内でこの問題を解決するのが、安全性を担保するひとつの目安だと思います。

この問題を解決するアプリケーション・アーキテクチャとして注目されているのがDCI(Data Context Interaction)です。

このスライドでは、OFPが提供するトレイト、型クラスという新しい言語要素(「OFP新三種の神器」)が、DCIといった新しいアプリケーション・アーキテクチャを可能にするという点の説明を行う予定でした。

モデリングの流れ

DCIのモデリングの流れとしては:

  1. ユースケース・モデルの作成
  2. コラボレーションとコラボレーションから呼び出すロールを抽出
  3. コラボレーションを実現するアプリケーション・ロジックを分解してロールに配備
  4. ロールをドメイン・オブジェクトに編み込み。コンテキストで全体を統合。

となるかと思います。ボクが確認した範囲では、アプリケーション・ロジック専用のオブジェクトを生成したり、コンテキスト側でアプリケーション・ロジック(の一部)を実現するのではなく、あくまでドメイン・オブジェクトに編み込むロールにロジックを分割するようです。

つまり、この理解が正しければユースケースの責務をドメイン・オブジェクトに分割配備する伝統的なオブジェクト・モデリングの手法を軸としながら、ユースケース由来の責務をコンテキストに紐づいたロール側に配備することで、モジュール化を実現しているのがDCIということになります。

実装技術

ロールをオブジェクトに編み込む実装技術として、トレイトと型クラスが有力です。

現時点では、書籍の「Lean Architecture: for Agile Software Development」がDCIについて最も情報量があるのではないかと思います。この本では、DCIについての主な実装方法として、CとRubyの2つの言語での実装が主に取り上げられており、付録としてScalaも取り上げられています。

Cの実現はマクロを使ったものでやや強引な印象です。Rubyの実現はmoduleを使った動的型付ならではのメタプログラミング的な手法で、プログラマに負担をかけないのが美点です。

ただ、普通の静的型付け&OOPでの実装技術となるとなかなか難しく、Javaで実現する場合は相当量のボイラープレイト、繋ぎコードが必要になりそうです。この問題に対する解として期待されるのがScalaのトレイトです。

トレイトによる解

DCIでは、Scalaのトレイトによる実装を選択肢の一つとして挙げています。たとえば、「Lean Architecture」で紹介されているプログラム例の一部を以下に引用します。

val source = new SavingAccount with TransferMoneySource
val sink = new CheckingAccount with TransferMoneySink
source.increaseBalance(100000)
source.transferTo(200, sink)

SavingAccountクラスのオブジェクトを生成する時に、ロールを実現したTransferMoneySourceトレイトをwith句で編み込んでいるのがポイントです。この(ユースケース由来の)アプリケーションロジック向けの機能を事前にSavingAccountクラス側で提供しておく必要はなく、アプリケーションロジックでの必要に応じてロールを編み込みます。ユースケースから派生したロジックを、直接ドメイン・オブジェクトに分散配備するのではなく、ユースケースに紐づいたロール側にまとめておけるのでモジュール化も保てるというわけです。

型クラスによる解

Scalaでは、トレイとに加えて、型クラスという新しい言語機能が提供されています。(正確には暗黙パラメタと暗黙変換によってライブラリで型クラスを実現することができます。)型クラスは、基本的にはジェネリックプログラミングのカテゴリの言語要素だと思うのですが、Haskellで実用化され、関数型の枠組みの中でうまく機能しているのでたので広義の意味では関数型の特徴的な言語要素ということも可能かと思います。

Scalaでの実現であるScalazを実際に使ってみると"OOPにも型クラスの導入が可能で、実用上も有益である"のかなと思いますが、プログラミング言語理論は素人なので、このあたりの事情はよくわかりません。

ひとつ言えるのは、Scalaでは型クラスは非常にうまく機能しており、Scalaの提唱するObject-Functional Programmingの重要な基盤の一つになるだろう、ということです。

DCIをトレイトで実装する場合の問題点は、with句を使うコーディングとなるのでロールをドメイン・オブジェクトに編み込むところがハードコーディングとなることです。コンテキストが複数のロールを扱うときに、これらのロールを束ねるメカニズムもないので、このあたりで拡張性やモジュール化で問題が出てきそうです。

型クラスの場合は、コンテキスト毎にアプリケーション・ロジック、ロール、ドメイン・オブジェクトの対応関係の組を柔軟に指定することができるので、拡張性、モジュール化の能力に優れているのではないかと思います。そういう意味で、トレイトではなく型クラスが、ScalaにおけるDCI実現の本命ではないかと考えています。

DCIの評価

「このスライドでは、OFPが提供するトレイト、型クラスという新しい言語要素が、DCIといった新しいアプリケーション・アーキテクチャを可能にするという点の説明を行う予定」だったわけですが、改めてじっくり検討してみると、DCIはとても魅力的なアプリケーション・アーキテクチャではあるものの、実際のシステム開発への展開はまだまだ難しそうというのが実感です。

また、アプリケーション・ロジック専用のオブジェクトは第一級のモデル要素としては考えていないというのが、DCIがボクの好みとずれがある点です。ボクとしては、アプリケーション・ロジック、ロール、ドメイン・ロジックの3階層で責務の分割配備を考えたいと思っています。(このようにして抽出したアプリケーション・ロジックは、ドメイン・ロジックそのものなので、ドメイン・ロジック&ドメイン・オブジェクトとしてドメイン・モデル内に還元する、という考え方であればDCIとは矛盾しません。どちらの考え方にした方が、実際のアプリケーション開発で有効なのか、もう少し様子をみて判断したいと思っています。)

以上がOFADについてひと通り通して考えてみた上での実感です。

EDA

アプリケーション・ロジック、ロール、ドメイン・ロジックの3階層で責務の分割配備を行うためには、DCIでいうところのコンテキストを、アプリケーション・ロジックを配備するモデル要素に格上げするような、アーキテクチャが有効ではないかと考えます。仮にこのモデル要素をコラボレーションと呼ぶことにしましょう。(「コラボレーション」という用語はミスリードのような気もするので、他の名前を編み出したほうがよいかもしれません。)

このコラボレーションを、実際のアプリケーション・アーキテクチャに組み込む場所ですが、クラウド・アプリケーションでは、「EDAとオブジェクトと関数」で取り上げたEDAをベースとしたアーキテクチャが有力ではないかと考えています。

このアーキテクチャにあるコラボレーションをイベント・コンシュマーとしてEDA内に組み込むわけです。この時に、コラボレーションの通信相手となるロールを型クラスの機能を用いてドメイン・オブジェクトに編み込みます。

この方式では、イベント発生に付随した複数の疎結合のユースケースが並行動作することを自然に扱うことが事ができます。また、EDAの特質上、非同期処理も自然に扱えるのという長所もあります。

そういう意味で、DCIというアーキテクチャを単独で考えるのではなく、EDAのアーキテクチャの中にDCI的なアプローチも取り込みながら、EDAの枠組みで全体のアーキテクチャ(モデリング・ビュー、コンポーネント・ビュー)を考えていくのが、クラウド時代のOFADを整備していく上で有力なアプローチではないかというのが現時点での考えです。

諸元

当日使用したスライドは以下のものです。(PDF出力ツールの関係で、当日は非表示にしたスライドも表示されています)

このスライド作成の様子は以下の記事になります。

まとめは以下の記事です。

回顧は以下の記事になります。

2012年3月29日木曜日

メタモデル

3月19日(月)に要求開発アライアンスのセッション『Object-Functional Analysis and Design: 次世代モデリングパラダイムへの道標』を行いましたが、説明を端折ったところを中心にスライドの回顧をしています。

今回「メタモデル」として用意した以下のスライドを説明します。

以前からSimpleModelingというOOADの開発手法の一環でDSL駆動開発向けのOOADメタモデルを整備しています。この本の内容はクラウド・プラットフォーム登場前のものですが、クラウド・プラットフォーム向けにいくつか拡張を行ってきました。

また、今回スライドを作りながらOOADと関数型言語の関係を考えてきたわけですが、その考察の中で鍵となるモデルとして浮かび上がってきたデーターフローというモデル要素を追加することにしました。

まとめると、クラウド以降に以下のモデル要素が追加されたことになります。これらのモデル要素は図では白抜き文字にしています。

  • UX
  • サマリー
  • データフロー
  • メッセージフロー
  • データフロー

以下で順に説明します。

ここまでの拡張

このSimpleModelingに対してここまでクラウド向けモデリング向けに追加してきたモデル要素は以下のものです。

  • UX
  • サマリー
  • データフロー
  • メッセージフロー
UX

「OFADの要素技術/関連技術」でも説明しましたが、Ajaxやスマートデバイスの興隆によるリッチなGUIのニーズの高まりを背景にUCD(User Centered Design)、UX(User Experience)という技法が注目されています。以前から要求仕様の一環として画面設計を行うケースはあったわけですが、UCD/UXはそのアプローチを利用者視点でより理論的に進めたものということができます。

UXは比較的最近の言葉ですが、UCDは「ユーザー中心設計」にもある通り、かなり古くからあるモデリング技術です。一般消費者向け商品のモデリングとして発展してきたものが、Webシステムによる一般消費者向けのサービスが大きなマーケットに育ってくる中で、ITシステムの要求仕様のためのモデリング技法として注目されてきているという流れだと思います。

今後は、エンタープライズ・システムでも、ソーシャルメディアといった軸でビジネス的な意味での顧客とのコラボレーションを設計していかなければならないと考えられ、そのなかでUCD/UXが利用されていくのではないかと思います。

こういったモデリング技術の動向を取り入れるために、UX(User Experience)をユースケースの前段に配置しています。ここでのUXは、Ajaxやスマートデバイスを対象とした比較的狭い範囲のUCD向けを想定していますが、ソーシャルメディア上のコラボレーションという意味では、図の右側ビジネスモデルの所にUCDを持ってくることも考えられます。従来からあるビジネス・プロセス、ビジネス・ユースケースのアプローチとUCDの関係をどのように整合させていくのかはまだイメージが湧いておらず、ジャストアイデアというところなのでメタモデルの図には載せていません。

UXとユースケースは、「OFADの要素技術/関連技術」で説明した「(2)Ajaxやスマート・デバイスなどのリッチなGUI向けのUIデザイン(+要求仕様)」について、「従来のユースケースと部分的に技術がかぶってくるので、役割分担を考えていかなくてはなりません。利用者とのインタラクションはUXを用い、システム側はエッセンシャル・ユースケースに徹するという分担が考えられます。」というアプローチを考えています。たとえば、UXでペルソナを作成し、これをエッセンシャル・ユースケースに落とすという連携です。

ただ、通常の定型業務向けの業務アプリケーションは、ビジネス・ユースケース(や業務フロー上)でロールを抽出し、このロールの責務を明確にするという従来からあるOOADのモデリングの方が向いていると思われるので、必ずしもUXの導入がよいというわけでもなさそうと考えています。 その場合でも、ロール・モデリング後に、要求仕様としての画面設計(ちょっと言葉が変ですが、画面モックアップぐらいがよいかも)の中でUX的な技法を適用していくのは有効そうです。

サマリー

サマリーは、「要約エンティティ」という記事で説明したエンティティです。

従来から企業システムは、(1)同期型のオンラインシステムと(2)非同期型のバッチの2つのサブシステムから構成されています。ERモデルでは、summaryエンティティという非同期型バッチが計算した要約情報を格納するのに適したエンティティを使うこともあります。

クラウド・プラットフォームでは、こういったバッチ的な非同期処理(さらにストリームも入ってきます)が大前提になるので、サマリーというエンティティを第一級市民のモデル要素として扱っていくことにしました。

メッセージフロー

メッセージフローは、ユースケースから責務の抽出とオブジェクトへのアロケーションを行うために使用するロバストネス図のクラウド・アプリケーション向けの代替、発展形として導入したモデルです。また、クラウド・アプリケーションの全体像を簡潔に記述する目的にも使用できます。

クラウド・アプリケーションでは、非同期処理が重要な構成要素になります。また業務端末からのデータエントリ処理、夜間バッチといった定型ジョブの起動だけでなく、企業顧客や、消費者からの様々なイベントが高頻度にあがってくるようになるので、アプリケーション・アーキテクチャもイベント駆動型アーキテクチャ(EDA)に変わってくることになるでしょう。

アプリケーション・アーキテクチャがEDAになってくると、従来からあるロバストネス図では、機能不足のためモデルを記述するのが難しくなってきます。この問題を解決するために考案したのがメッセージフロー図です。

メッセージフロー図は、制御フローとデータフローを同じモデル内に記述するために考えたモデル図です。基本的にロバストネス図の発展形であり、宣言的、演繹的なモデルではなくて、実例ベースの帰納的なモデルです。このため、DSL駆動によってプログラムの生成を行うためのソースとして使用することは想定しておらず、ユースケースを実現(realization)するための補助線として使用するラフスケッチという運用になります。

今回の拡張

今回の関数型に関する一連の考察でデーターフローを新規に追加することにしました。

このデーターフローは、アプリケーション・モデルの実現モデルに入ります。

スライドで用いた図では、イベント→状態遷移→データフローのパスになっていますが、「EDAとオブジェクトと関数」で考えたように、実用的には状態遷移を飛ばしてイベント→EDA→データフローにしてしまう方式にしていこうと思います。

この場合、イベント処理エージェントやイベントコンシュマーの実装の中で、必要に応じて状態機械を使用することになります。また、現在OOADやOOPで用いられているDbCの事前条件、事後条件による状態遷移の記述を活用し、状態機械を間接的にモデル化していくアプローチも併用していくことになります。

イベント

従来からイベント・エンティティはSimpleModelingの中軸となる非常に重要なモデル要素です。永続的なビジネス・イベントはエンティティでもあるので、ドメイン・モデルとアプリケーションを接続するハブとして機能します。

今回の図には直接見えてきませんが、イベント・エンティティの実現方法として、「EDAとオブジェクトと関数」で説明したように、ちょっと実装よりになりますが、状態機械ではなくEDA的なアーキテクチャを導入するのが現実解ではないかと考えています。

何故このあたりを細かく考えているのかというと、メタモデルの精度がDSL駆動開発の基盤になるからです。イベント&EDA周りでどのようなDSLを定義していくのかは今後の課題ですが、クラウド・アプリケーションにおけるイベントの実現方式もかなり視界が開けてきました。

諸元

当日使用したスライドは以下のものです。(PDF出力ツールの関係で、当日は非表示にしたスライドも表示されています)

このスライド作成の様子は以下の記事になります。

回顧は以下の記事になります。

2012年3月28日水曜日

EDAとオブジェクトと関数

3月19日(月)に要求開発アライアンスのセッション『Object-Functional Analysis and Design: 次世代モデリングパラダイムへの道標』を行いましたが、説明を端折ったところを中心にスライドの回顧をしています。

今回はセッションで説明したモデルの改良案として、EDA(Event-Driven Architecture)の導入を行ってみます。

元のスライド

オブジェクトと関数型の繋ぎのところを具体的に考えるために2つスライドを作成しました。

「イベント→データフローの流れ」は、OOPレベルの細かい処理の流れを示しています。

「ユースケースと関数」は、OOADの観点からユースケース・モデルからOOPを経て、FPに至る流れを示しています。

OOADを軸としたアプローチが検討対象にしているので、いずれも(協調→)状態機械→アクションというオブジェクト・モデルとして素直な連携を軸に考えています。

実際に図にして考えてみると、(協調→)状態機械→アクションという流れのモデリングはあまり便利そうに見えません。協調→状態機械のモデリングは難しいですし、仮にモデルをきちんと作ったとしても、モデルと実装の乖離が大きいため、実装が進むにつれモデルが朽ちていきそうです。

理論的には正しくても、便利でないものは使われないので、もう少し実装に近いモデルで再検討してみます。

EDA

クラウド・アプリケーションのアプリケーション・アーキテクチャでは、EDA(Event Driven Arachitecture)やEIP(Enterprise Integration Patterns)といったSOA、エンタープライズ系のアーキテクチャの技術が有効ではないかと考えています。

そこで、OOAD的な(協調→)状態機械→アクションではなくて、EDA上での実現を考えてみました。

イベント→データフローの流れ

スライド「イベント→データフローの流れ」の改良案です。

OOAD的には、イベント発生が状態機械に状態遷移を発生させ、状態機械のアクションによってプログラムの処理がキックされるというモデルになりますが、「状態機械→アクション」の部分をEDAに取り替えてみたのが以下の図です。


図に登場するEDAの構成要素は以下の通りです。

イベント
システム内で発生する事象
イベントプロデューサ
イベントを生成するエージェント
イベントチャネル
イベントプロデューサとイベントコンシュマーを結び付けるチャネル
イベント処理エージェント
イベントのルーティングを行うエージェント
イベントコンシュマー
イベントを受信するエージェント

イベントプロデューサがイベントを発生させると、イベントチャネルからイベント処理エージェントを経由してイベントコンシュマーにイベントが通知されます。

イベントコンシュマーは、元のOOADの図におけるアクションに対応します。ここで、イベントに対するアプリケーション・ロジックを記述します。

イベントコンシュマーの実装では、データフローと関数型でアプリケーション・ロジックの中核部分を記述し(データフローの実装技術)、イベントコンシュマー本体でエンティティの更新を行うという役割分担(オブジェクトと関数の連携(2))を採ることになります。

EDAの構成を採ることで、イベント発生とアプリケーション・ロジックを疎結合にし、アプリケーション・ロジックの追加や拡張を容易にします。複数のユースケース・コンテキストがドメイン・モデル上に重なってくるようなアプリケーションでは、ユースケース・コンテキスト(あるいはユースケース)毎にイベント・コンシュマーを用意することで、システムのモジュール化を促進します。

また、イベントチャネルを介在させることで、MOMやESBを使用した非同期処理での実装も可能になります。

実装

論理モデルとして、この構成でモデリングしておいても、設計/実装の段階ではイベントプロデューサからイベントコンシュマーを直接同期型で呼んでしまうという実現方法を選択することも可能です。

実装時のイメージとしては、右のようなものを想定しています。基本的な処理はイベントチャネルを介さず、同期型でイベントコンシュマーにイベントを通知し、処理結果を持ち帰ります。一方、それ以外の処理はイベントチャネル経由で非同期にイベントコンシュマーにイベントを通知して処理を行います。

ユースケースと関数

スライド「ユースケースと関数」の改良案です。

OOAD的な視点では、ユースケースから関数までの流れが重要になります。

ユースケースは自然言語で記述した物語ですが、システム開発につなげるためには、もう少しシステムよりのモデルを用意してユースケースから使用するような形に持ってくる必要があります。ここでは、タスクとサービスというモデル要素を用意しました。

タスクは、ユースケース・フローにおけるシステムの使用方法を定義したものです。システムが提供するサービスの使い方(パラメタなど)を定めます。

サービスはイベントプロデューサを呼出して(サービス自身がイベントプロデューサも可)、EDAのメカニズムの上で処理を進めます。ここから先は前節で説明した流れで処理が進んでいきます。(イベント処理エージェントは宣言的な定義で記述する事が多いと思われるので図ではOOPから外していますが、OOPやFPあるいはDSLによる実現が可能です。)

DSLによるモデル記述と実装への展開

EDA上でオブジェクト・モデルと関数型を連携させていく方法についてやや実装よりに細かく考えてきました。

このあたりは、g3フレームワークやSimpleModelerで試行錯誤しながら色々と検討してきた点なのですが、ここでいっているような形では状態機械にはこだわらず、まずEDAベースでモデリングとフレームワークを構築するのがよさそうというのが最近の考えです。そのようなこともあり、今回ちょっと腰を据えて考えてみました。

今回考えたモデルをベースに、SimpleModelerとg3フレームワークでどのようにDSL化(モデルDSLとフレームワークDSL)していくのかというのが次の課題です。

諸元

当日使用したスライドは以下のものです。(PDF出力ツールの関係で、当日は非表示にしたスライドも表示されています)

このスライド作成の様子は以下の記事になります。

回顧は以下の記事になります。

2012年3月27日火曜日

オブジェクトの世界と関数の世界

3月19日(月)に要求開発アライアンスのセッション『Object-Functional Analysis and Design: 次世代モデリングパラダイムへの道標』を行いましたが、説明を端折ったところを中心にスライドの回顧をしています。
「オブジェクトの世界と関数の世界」として用意した以下のスライドを説明します。


このスライドは元々、以下の2つの情報を表現するために用意していたのですが、いろいろ書き込んでいくうちに、OFADでのモデル変換の流れの側面が大きくなってしまいました。
  • オブジェクトの世界と関数の世界は併存するのが必然
  • アプリケーション・モデルの実装側はできるだけ関数型にしていく
このため、同じような情報を持つスライドをセッションでは2つ省略しましたが、逆に、このスライドでは、「OFADでのモデル変換の流れ」の説明になってしまい、肝心なことの説明ができなくなってしまったので、この記事で補足します。

オブジェクトの世界と関数の世界は併存するのが必然

オブジェクト指向技術は、元々はシミュレーション技術に根っこがあり、その最も重要な軸は、(経験則的な)人間の認知モデル、メンタルモデルをそのままモデルとして使用している点です。
このため、要求モデルを記述する際に、普通の人が把握できる範囲のモデルにおさまることが期待できます。さらにオブジェクト指向言語を使うことで、要求仕様から実装まで同じセマンティクス、インピーダンス・ミスマッチなしで一気通貫に記述できるというのがOOADの最大のアピールポイントです。(OOの重要なメリットである情報隠蔽による安全性やポリモーフィズムによる拡張性は、その次ぐらいに重要な項目といえます。)
たとえば、DDDのUbiquitous Languageで、用語集からドメイン・モデル、さらにOOPでの実装まで一気通貫に共通化できるのはこのような理論的な背景があるからですね。
一方、振舞いの記述、アルゴリズムの記述は、情報科学や数学のバックグラウンドを持つ関数型に一日の長があります。(関数型はモデルの種類の名称としては一般的ではないので、以下では数理モデルという用語を使うことにします。)
とはいえ、数理モデルは、以下の問題があるので汎用的な意味で要求モデルを記述するモデルに採用するのは困難です。
  • 問題を数理モデルで記述できるとは限らない
  • 数理モデルは情報科学や数学のスキルがないと作成できない
  • 数理モデルは情報科学や数学の素養がないと内容を理解できない
要求モデルとして数理モデルで記述できる範囲のモデル、顧客が数理モデルの素養がある、という条件がうまくハマった場合には、一気通貫に要求モデルから実装コードの生成まで持っていけるので、極めて強力です。
このため、大枠はオブジェクト・モデルで考え、サブシステムまたはモジュール単位で数理モデルで要求モデルを併用するようなアプローチが有効でしょう。
いずれにしても、数理モデル一本ということは現実的には不可能なので、オブジェクト・モデルは必須です。全体の大枠は清濁併せ呑むオブジェクト・モデル、ぴったりとハマったところは数理モデル、ハマらなかったところはオブジェクト・モデルで記述して併用・併存するのが現実解です。

アプリケーション・モデルの実装側はできるだけ関数型にしていく

要求モデルでは、大枠はオブジェクト・モデルが必須で、一部条件を満たしたケースで関数型/数理モデルを併用することになります。エンタープライズシステムの場合、現実的には当面関数型/数理モデルを使うことはほとんどないでしょう。つまり、事実上要求モデルはオブジェクト・モデルということになります。
しかし、オブジェクト・モデルを実装する過程の中で、関数型を使えるポイントが色々とあります。一つは関数型言語を使った関数型的なプログラミングですし、より抽象的なモデルとしてはデーターフローが有力です。
図中のオブジェクトの世界では、現実世界→ドメイン・モデルのラインとやりたい事の物語→ユースケース・モデル→協調→状態遷移→アクションのラインがありますが、前者のドメイン・モデル・ラインはオブジェクト・モデリングがよいでしょう。
一方、後者のユースケース・モデル・ラインは、オブジェクト指向的によい実装方法がないので、可能なかぎり関数型にしていくのが望ましいところです。たとえばデーターフローで記述できるところを見つけて、これをデータフローモデル→関数型またはDSLで記述していくというアプローチですね。この部分をいかに関数型の方向に倒していくのか、というのが今後のプログラミング技術やモデリング技術の方向性を見ていく上で重要な視点ではないかと思います。
この場合、関数型で記述したアルゴリズムが扱う事実の情報、いわゆるファクトモデルとして、オブジェクトのドメイン・モデルを使うのがよい組み合わせです。

省略したスライド

内容が重複するので省略したのは以下の2つのスライドです。

上側は「 オブジェクトと関数の連携(3)」として用意していた図です。オブジェクトと関数の接点として、当面はデータフローが現実解かな、という内容です。


下側は「Domain-Driven Design (DDD)」で説明したとおり、OOADの中でのDDDの位置付けを説明する内容です。

OOPは不要?

昨日たまたま某所で教えてもらったのですが、以下のような流れもあるみたいです。(注意:一年前の記事です)
情報科学やアルゴリズムの勉強にOOPは不要でFPのみでよい、というのは一理あります。
現状ではエンタープライズ向けにはOOPが支配的な言語パラダイムである(COBOLがあるので"新規開発では"という注釈つきかもしれません)、システム、サブシステム粒度のモデルの記述方式に何を用いるのか、といった点は置いておくとしても、情報システム構築の要求モデルにオブジェクト・モデルが必須である以上、長期的に見てもエンジニアのスキルとしては引き続きOOPは必要と思います。
とはいえ、OOPが圧倒的、絶対的という訳ではなく、条件付きで有効というように相対化していく流れを象徴する出来事であるのは確かです。

諸元

当日使用したスライドは以下のものです。(PDF出力ツールの関係で、当日は非表示にしたスライドも表示されています)
このスライド作成の様子は以下の記事になります。
回顧は以下の記事になります。

2012年3月26日月曜日

Domain-Driven Design (DDD)

3月19日(月)に要求開発アライアンスのセッション『Object-Functional Analysis and Design: 次世代モデリングパラダイムへの道標』を行いましたが、説明を端折ったところを中心にスライドの回顧をしています。

「Domain-Driven Design (DDD)」として用意した以下のスライドを説明します。



セッションの全体構成は以下のようになっています。

  • 関数型プログラミング
  • Object Functional Programming (OFP)
  • Object Functional Analysis and Design (OFAD)
  • 応用

この中で4番目「応用」は、今OOADやクラウド・プラットフォームで話題となっている技術がOFADでどのような影響を受けそうなのかということを考えてみる趣旨のセクションです。

具体的に考えてみることで、OFADへのイメージがより明確になるかなと思ったのですが、残念ながら時間の関係で省略することになってしまいました。「応用」は33枚目からなのですが、50分だと30枚ぐらいが目安ですね。

上記スライドは、その「応用」の一つとしてDomain-Driven Design (DDD)を取り上げたものです。DDDはいうまでもなく、エリック・エヴァンス氏の以下の書籍によるドメイン層の設計技法です。

OOADの中での位置付け

まず、OOADの中でのDDDの位置付けについて確認しておきましょう。以下は、当日は他のスライドと内容がかぶるので非表示にしていたスライドです。


この図ではOOADを、大きくクラス図を中心としたドメイン・モデリングとユースケース/協調を中心としたアプリケーション・モデリングの2つに分けています。

さらに、ドメイン・モデリングは、ドメイン・モデルそのものを作成する業務モデリング&要求モデリングとドメイン・モデルの実装方法をモデル化するシステム・モデリング&設計の2つに分けることができますが、DDDがカバーするのは後者システム・モデリング&設計の所です。

セッションのテーマであるOFADでは、"関数型の所は主にユースケース、協調に関するモデリング技術と関係を持ってくるのでDDDは直接影響を受けないだろう"、というのがこのスライドのDDDに関する部分の趣旨です。

このスライドを使っていた場合は、以下のようなことを口頭で補足する感じです。

まず、ドメイン・モデルという観点では関数型はルール・モデルに影響を与える可能性があります。とはいえ、ルール・モデルは関数型をさらに発展させた論理型と対応させるべきモデルなので、関数型の段階の影響はそれほどないのではないかと思います。

それより、関数型言語で実現するDSLでルール・モデルを記述するようなアプローチはありそうなので、その点は継続して動向を見ていく必要はありそうです。

[参考]業務モデリングと要求モデリング

ちなみに前者の業務モデリング&要求モデリングは、以下のような本が役に立ちます。

(翻訳は分かる範囲で載せていますが、翻訳品質は未チェックです。今回調べてみて分かったのですが、翻訳の方は良い本でもすぐに絶版になってしまいますね。早く電子出版に移行して欲しいです。)

DDDによる設計と関数型言語

OFADによってDDDの位置付けが変わったり、DDDによってOFAD側に影響が出るようなことはなさそうですが、DDDの設計・実装技法と関数型言語の関係はまた別です。

最初のスライドに戻ると、DDDのパターンの中でいくつか関数型的な手法が見られるので、それをピックアップしています。

まず、重要なのは:

  • Declarative Design - Domain Specific Language
  • A Declarative Style of Design - Composite Specification
  • Declarative Style

という形で宣言的な設計スタイルを推奨していることです。宣言的にすることでDSLを適用できたり、仕様の合成もできるようになるわけですね。関数型と相性がよい設計スタイルです。手続き型的な手法はこういったことができずに、どうしても手作業が多くなってしまいます。

OFAD的に翻案すると「いかに、手続き型な部分を減らして、関数型的な部分(DSLを併用)を広げていくのか」、というのが今後のソフトウェア設計の軸になるのではないかと思います。

直接関数型を意識しているのは以下の項目。

  • Side-Effect-Free Functions
  • Closure of Functions

Context Mapは、複数のドメイン・モデルを併用するときの技法です。最近だとLensのような代数的/圏論的な手法も登場してきているので、こういった手法を適用できる可能性があります。

Value Objectは、Entityの内容を持ちまわったり、協調の中で発生する揮発性の情報を持ちまわるためのオブジェクトで、DTO的な用途のオブジェクトを、モデリング上の一級市民に格上げしたものです。定義的にはID(がモデル上の意味)を持たないオブジェクト、オブジェクトの同一性の比較がIDではなくて、格納されている値の比較で行われるオブジェクトということです。

DDDでは、Value Objectとしていますが、基本的な値を表現するオブジェクトと、XML的な構造を持ったオブジェクトは分けたほうがよいと思うので、ボクは前者をValue、後者をDocumentと使い分けています。

Value Objectは、不変オブジェクトであることが推奨されており、関数型の代数的データ型や永続データ構造(関数型言語の技術マップ)といった技法で実現するのがぴったりはまります。(とはいえ、性能問題やプログラミングの手間もあるのでDDDには「Special Cases: When to Allow Mutability」というノートも書いてあります。実際問題として、Value Objectを完全に不変オブジェクトにするとプログラミングの手間が大変ですので、プログラマの習性としては分かっていても可変オブジェクトにしてしまいがちです。そこで、不変オブジェクトとこれをビルドするためのBuilderを自動生成しようというのが拙作のSimpleModelerのアプローチです。)

DDDは、筋のよいOO設計、OOP実装技法の経験則という側面が大きいと思いますが、DDDが出版された2003年当時OOP/OOAD全盛の中でも、関数型(的なアプローチ)の存在感はなかなか大きい感じがします。

関数型言語が実用化された今となっては、できるだけDSL&関数型的な手法で実現する範囲を大きくしていくことが、新しい経験則になっていくのではないかと思います。

具体的には、以下に書いたようなことですね。

諸元

当日使用したスライドは以下のものです。(PDF出力ツールの関係で、当日は非表示にしたスライドも表示されています)

このスライド作成の様子は以下の記事になります。

回顧は以下の記事になります。

2012年3月23日金曜日

DSL指向プログラミング

3月19日(月)に要求開発アライアンスのセッション『Object-Functional Analysis and Design: 次世代モデリングパラダイムへの道標』を行いましたが、説明を端折ったところを中心にスライドの回顧をしていきたいと思います。

「アプリケーションの階層と役割」として用意した以下のスライドを説明します。

なんだかんだいっても関数型言語はやはり難しいし、さらにオブジェクトと合体したオブジェクト関数型言語となると、使うのがさらに難しいというのが実際のところでしょう。

ScalaはBetter Javaとして使う道もあるので、それに徹すれば普通のOOプログラマにとって、習得はそれほど難しくはありませんが、プロジェクトで使用する第一プログラミング言語を選定する際に、Better Javaという理由だけでプログラミング言語を定番言語から新興言語にスイッチするのはリスクが大きすぎます。

また、現状Scalaの入門/解説の書籍、記事の多くは「関数型」の華やかなところにスポットライトを当てているので、Better Javaのための情報はなかなか入手することができません。この点でも、Better Java効果を期待してScalaを導入するのは難しくなっています。(拙作の入門書はBetter Javaにフォーカスしています、と宣伝。Amazonでは評判は悪いみたいですが(笑)。)

このため、OFADの以前に、「OOPもうまく使いこなせていないのに、そもそも関数型言語が流行るの?」という疑問が出てくることが想定されるので、それに対する解として用意したのがこのスライドです。

従来から、アプリケーションをスクラッチで全部書くというのは稀で、普通は何らかのフレームワークを使用し、その土台の上にビジネス・ロジックを構築していきます。SIerや大手のソフトウェアハウスは、自分の事業ドメインに特化したフレームワークを持っているのが普通ですし、そうでない場合もOSSのフレームワークを使用するのが普通です。

データ設計は上流で行うとして、プログラマの仕事は用意されたデータモデルを操作してフレームワーク上にビジネス・ロジックやUI操作を宣言的あるいは手続き的に記述していくことに費やされます。この場合、OOPの知識はそれほど必要ではなく、フレームワークのしきたりの理解のほうがより重要になってきます。XYZという名前のフレームワークがあったとすると、OOプログラミングというより、XYZプログラミングというようなプログラミングスタイルになってくるわけです。

このXYZプログラミングをJavaで行うと、フレームワークとJavaの間にボイラープレートと呼ばれる繋ぎコードが沢山必要になって、生産性が今ひとつ上がりません。また、以前好まれていた宣言的な記述をXMLで行う手法は、(1)XMLの編集が大変、(2)XMLとJavaの繋ぎのところで静的型付けの効果がなくなる(プログラムが脆弱になる、デバッグが大変)、という問題があるため最近は回避する方向にあります。最近主流なのはアノテーションによる方法ですが、記述力が限定的なので、万能というわけではありません。

この問題の解として今後主流になると予想されるのが関数型言語によるDSLです。関数型言語は言語の自己拡張性によって内部DSLの実現に向いていますし、Scalaは各種文法糖衣で内部DSLの実現をさらに容易にしています。

DSLは(1)大きくプログラミング言語に埋め込む内部DSLと、(2)独立した専用言語の外部DSLの2種類に分けることができますが、前者はさらに(1a)モデルを記述するDSLと(1b)フレームワークのAPIとしてのDSLに分けることができます。

この(1b)フレームワークのAPIとしてのDSLが、今後最も注目される技術の一つと思います。今回のセッションでも、Hadoop向けDSLであるSpark、Scaldingと、ESB(Enterprise Service Bus)であるApache Camel&EIP向けのScala DSLを紹介しました。また、丸山先生の「エンタープライズ・クラウドの現在」ではScala DSLベースのWebアプリケーションフレームワークPlay 2.0が取り上げられていました。

DSL指向フレームワークとDSL指向プログラミング

図では、アプリケーション層、DSL層、フレームワーク層の3層でのアプリケーションアーキテクチャを示しています。(今考えてみると、アプリケーション層は、ビジネス・ロジック層あるいはアプリケーション・ロジック層の方がよかったような気がします。)

このDSL層とフレームワーク層は、極少数のエンジニアが作成することになるので、OOPでも関数型でも、高度な技術を持っていることを前提としてかまいません。逆に、このフレームワーク&DSLが、いかに高機能かつ使いやすいものになるのかが、SIerやソフトウェアハウスの核心的競争力になるので、関数型でも何でもいかに高度な技術であっても使えるものはきちんと使う、という事になるはずです。つまり、この用途にオブジェクト関数型言語が利用されるようになるのは、必然といってよいでしょう。

もちろん、フレームワーク層で使っている技術の難しさがアプリケーション層に出てしまってはいけません。

そこで登場するのがDSLです。Spark、Scalding、Apache Camel&EIP向けのScala DSLの例を見ても分かるとおり、下層のフレームワーク、ミドルウェアの難しさを完全に隠蔽して、プログラマには論理的なデータフローに見せることに成功しています。これまでは、これをJavaで実現しようとしたものの前述したような問題が出てきて今ひとつうまくいかなかったわけです。

アプリケーション層については、OOPや関数型の知識があればより効率的なプログラミングが可能になるのは言うまでもありませんが、DSLでビジネス・ロジックを記述していくだけであれば、OOPや関数型のスキルがあまりなくても大丈夫です。Scala DSLの場合は、DSLで記述するところはScalaで書いて、そこから先はJavaを使うという道もあるので、さらに導入の閾値は下がります。

アプリケーションはDSLつまり専用言語を用いたプログラミングを行うことになります。このように、従来的なAPIではなくて、専用言語であるDSLでの使用を前提としたフレームワークを今後、このブログではDSL指向フレームワークと呼ぶことにします。ある意味、前述したフレームワーク指向のXYZプログラミングをより進化させたものがDSL指向フレームワークによるプログラミングとうことになります。これはDSL指向プログラミングと呼ぶことにしましょう。

ボクが以前から取り組んでいるDSL駆動開発は、モデルをDSLで記述するのに加えて、DSL指向フレームワークによるDSLプログラミングも加えた、DSLを柱とした開発が、今後のソフトウェア開発の主軸になるのではないかという提案でもあります。このDSL駆動開発によって、モデリングとプログラミングが一体になる/できるというのがこのブログのタイトルである「Modegramming」の意図です。

関数型言語やオブジェクト関数型言語は、このDSL駆動開発という文脈で考えてみると、今後のソフトウェア開発における重要性がみえてきます。関数型言語は、メニーコアやクラウド・コンピューティングにおける並列、分散への対応でも必須の技術になりつつありますが、これに加えてDSL駆動という軸も合わせて視野に入れておく必要があるでしょう。ソフトウェア開発へのインパクトではDSLの方が、より広範囲で深いのではないかと思います。

諸元

当日使用したスライドは以下のものです。(PDF出力ツールの関係で、当日は非表示にしたスライドも表示されています)

このスライド作成の様子は以下の記事になります。

2012年3月22日木曜日

MindmapModeling「KDDIがO2O事業を検討、無印良品やファミマが参加し実証実験」

3月17日(土)に横浜モデリング勉強会を行いました。また、会場には(株)アットウェア様の会議室をお借りしました。参加された皆さん、アットウェア様、どうもありがとうございました。

この勉強会で、浅海が作成したモデルを紹介します。モデルはMindmapModelingの手法で作成しました。(勉強会で使用したチュートリアル)

今回から、モデル駆動開発をテーマにすることになりました。(1)MindmapModelingでドメイン・モデルの作成、(2)SimpleModelerでモデル駆動開発、の二回構成になります。今までは、雑誌記事などで未知の領域のドメイン・モデルを自然言語からの情報で作成することに主眼を置いていましたが、今回から実際に動作するドメイン・モデルを作成することが主眼となります。

モデリングの対象は、Internet Watch誌の記事「KDDIがO2O事業を検討、無印良品やファミマが参加し実証実験」です。この記事を素材にO2O向けのサイトのモデリングをテーマにしました。この記事は参考情報という位置付けで、O2O向けサイトの機能は各自で好きなように設定できるということにしています。

物語を作る

通常MindmapModelingの最初の作業は単語の抜き出しになるのですが、今回はある程度知識のある分野であり、システムを作るのが目的なので作るシステムの輪郭を早めに確定させるためには物語の作成から始めました。

「コンビニでクーポンで安く商品を買う」という一般客視点の物語を作りながら、この物語に登場する単語をドメイン・モデルの用語/エンティティとして抜き出しながら、登場人物、道具、出来事を中心にMindmapModelingの定めた分類に従って仕分けしていきます。

この結果、できた最初のマインドマップが以下のものです。(図をクリックすると拡大します。)

洗練

次の段階では、実装を想定して、登場人物、道具、出来事の洗練を行います。

通常のMindmapModelingでも、実装を意識したモデリングを行いますが、今回は実際にモデル駆動開発を行うので、モデリング中の意識もより具体的になり、実装よりのモデルになっています。

未知の領域のドメインモデルを作るときに、実装を意識しすぎるとXXXの販売システム、とかXXXの在庫管理システム、といったように自分の既知のシステムになってしまうことが多々あるので、純粋にドメイン・モデリングの練習の場合は、実装を意識しすぎないという方針にしています。(実装に落とし込めるモデルだけど、意識はしすぎないということです。)

そのため、今回のようにMindmapModelingでの実装前提のモデリングはかなり新鮮でした。実装を考えながらのモデリングは、思考が具体的になって面白いですね。

以上の作業を行った結果のマインドマップは以下のものです。

道具の構造を洗練させると同時に、システムの振舞いの中心となる出来事を整備しました。物語と一貫性を持たせながら、道具や出来事といったエンティティに肉付けしていくのがポイントです。

メタモデルの拡張

SimpleModelerの運用では、MindmapModelingでラフなモデルを作成した後、専用Scala DSLに変換して、これを編集してより詳細な実装レベルのモデルに洗練させることを想定しています。

ということで、MindmapModelingではブレインストーミング的な用途を想定した演劇のメタファの範囲でメタモデルを定義しています。

ただ、演習などではMinmapModelingでは最後までモデリングできた方がよいので、実装よりの拡張をするのがよいかなと考えています。そういう意図で、今回はモデルを作りながらBOI構造枝、「サービス」、「要約」とエンティティに対する構造枝「参照」を加えてみました。この構造枝を追加すると、"演劇のメタファ"からは少し外れてきますが、致し方のないところです。

次回

次回の勉強会は4月中旬に行う予定です。MindmapModel(各自で作ったもの、または浅海が用意したもの)を使ってモデル駆動開発の実践を行います。実装プラットフォームはPlay 2.0を予定しています。

SimpleModelerによるプログラムの自動生成は「自動コーディング」、「自動DDD」をキーワードにしています。

プログラムを生成するというより、ドメイン・ライブラリをプログラマに変わって自動的にコーディングしてくれるという意図です。また、自動的にコーディングされるコードはDDDに沿ったクラス構造(Value Object, Factory, Repositoryなど)になります。

アプリケーション・モデルはスタブの生成までで、自動生成されたドメイン・ライブラリを使用して機能を実装していくことになります。

モデル駆動開発に興味のある方はぜひご参加ください。