ECO(Enterprise Core Objects)は、デザインとランタイム環境の両方を提供する強力なアプリケーションフレームワークです。そのフレームワーク自体は、高い柔軟性、拡張性を備え、大規模なアプリケーションサービスセットを提供します。ECOフレームワークが提供するサービスの中には、リレーショナルデータベースへのオブジェクト属性のマッピング、保管、検索をハンドルする永続化サービスがあります。このフレームワークアーキテクチャの中では、ECO空間(ECO Space)は、中心的な役割を担っています。Borland Developer Studio 2006に搭載されたECO III以前までは、UMLクラスダイアグラムが、ECOでモデルをビジュアルに設計できる唯一のダイアグラムでした。しかし、ECO IIIでは、ステートマシンダイアグラムによって、クラスの振る舞いをモデル化することができるようになりました。
ステートマシンの概要
ECOでは、1つ以上のECOパッケージを定義することができます。モデルで指定したすべての情報(クラス、属性、オペレーション、関連、制約など)によって、ECOフレームワークは、アプリケーションライフタイムを通じて、このモデルを実行することができます。ランタイム時にECO空間は、アプリケーションライフタイム中に生成されたオブジェクトのライフサイクルを管理します。これらのオブジェクトは、作成したモデルで定義したクラスのインスタンスです。ある瞬間のオブジェクトの属性値は、そのライフサイクルの中での特定の状態を表します。そのような特定の状態を「状態(ステート)」と呼び、この「状態」を識別するためのラベルを追加することができます。あるイベントは、オブジェクトの「状態」を、ある状態から別の状態に移行させます。これを状態の「遷移」といいます。UMLでは、このイベントを「トリガー」と呼びます。ECOでは、トリガーは、クラスのメソッドとして定義されます。”Is Trigger”プロパティを設定すれば、メソッドをトリガーに変更することができます。これは、Delphi開発者には非常になじみのあることでしょう。すべてのDelphi開発者は、イベントドリブン開発のコンセプトを受け入れています。例えば、フォーム上のコントロールは、イベントのトリガーになることができます。そして、イベントは、オブジェクトをあるステートから別のステートに遷移させます。
ステートマシンダイアグラムのメリット
「メリットは何か」と尋ねられたら、「何が新しいのだろう」と自問するかもしれません。ステートマシンダイアグラムに関して本当に役立つのは、ある状態から別の状態へ遷移するフローを特定するビジュアルマップを手に入れることができるという点です。このマップの利点は、こうした情報をコードから読み取るよりも、はるかに簡単であるということです。ここには、すべてのビジネスロジックが含まれており、これに変更を加えるのは容易です。ステートマシンダイアグラムがどのようなものかを理解するために、注文の状態を表したステートマシンダイアグラムの例を見てみましょう。

図1 注文ステートマシンダイアグラム
このダイアグラムは、以下の項目を表しています。
・初期状態
・Pending、Denied、Approved、Referredの状態
・トリガー、ガード、エフェクトによる状態の遷移
・ガードによって定義された状態遷移の例
すべてのUMLステートマシンには、1つの「開始状態(イニシャルステート)」がなければなりません。この開始状態は、そのオブジェクトの実際の初期値を表します。この例では、”Pending”です。つまり、注文は、”Pending”の状態から始まり、”Denied”、”Referred”、”Approved”のいずれかの状態に遷移することができるのです。また、ここには、ビジネスルールの定義も見ることができます。「注文の合計数は、500未満である」という条件が真である場合のみに、”Pending”から”Approved”に遷移することができます。これをガード(Guard)と呼びます。また、ガードのほかに、遷移に対するエフェクト(Effect)を定義することができます。同じように、状態に対して、EntryアクションとExitアクションも定義できます。ECOは、ビジネスロジックの指定にOCL(Object Constraint Language)を使用します。実際、何が起こっているのかを、容易に理解できると納得できると思います。
では、ECOによる開発例を見ていきましょう。
ステップバイステップのサンプル
まず。新しいECO WinFormsプロジェクトを作成します([ファイル|新規作成|その他]を選択し[Delphi for .NET Projects]をクリックします)。
プロジェクトファイル用にアプリケーション名のとディレクトリ名を入力します。この例では、アプリケーション名はEcoOrderAppとします。

図2 新規ECO WinFormsアプリケーションウィザード
ウィザードが終了すると、フォーム、ECO空間、ECOパッケージが作成されます。プロジェクトマネージャを見て、生成されたファイルを確認してください。この記事では、ステートマシンにフォーカスしているので、ECOパッケージでOrderクラスを定義するところから始めましょう。[モデルビュー]を選択して、ツリーを開いてください。

図3 モデルビュー
デフォルトのECOパッケージは、”Package_1” と命名されます。これを、”OrderPackage” とリネームします。モデルビューで項目を選択し、右クリックして[名前の変更]を実行します。同じように、”Package_1Unit” を ”uOrderPackage” にリネームします。
次に、Orderクラスを定義するために、設計画面に移ります。ECOパッケージ項目を選んで、[図を開く]メニューを選択するか、ダブルクリックします。ここで、正しくビジネスロジックの定義から始めることができます。
ECOクラスを追加し、”Order” と命名します。そして、以下の属性を追加します。
Description: String
Units: Integer
Price: Integer
Total: Integer
オブジェクトインスペクタを使って、Total属性の「導出」プロパティをtrueに設定し、「導出OCL」に以下のOCL式を指定します。
units * price
これは、トリガーに対するガードを指定するときに必要となります。最初に示したステートマシンのサンプルでは、ビジネスロジックに合計値を使っていたことを思い出してみてください。次のステップでは、このクラスにトリガーを追加します。
ステートマシンのサンプルでは、トリガーが使われていました。それは、Approve、Deny、Referです。クラスを選択し、この3つのトリガーを追加します(ショートカットキーCtrl-Tを使うこともできます)。この結果、次のようになります。

図4 Orderクラス
ここまでできたら、ステートマシンを見てみましょう。クラスを選択して右クリックして、[追加|ECOステートマシン]を選択します。新しいダイアグラムは、クラス名(Order)が付加されています。ツールパレットを使用して、図1のように「状態」、「遷移」などの項目を追加してください。2つの「状態」間の「遷移」を追加したら、オブジェクトインスペクタを使って、「トリガ」プロパティを設定します。クラスで定義されたすべての「トリガ」プロパティは、図5のようにリストから設定できます。

図5 オブジェクトインスペクタ
最後のステップは、”Pending” と ”Approved” 間の状態遷移と、”Referred” と ”Approved” 間の状態遷移に対するガードの定義です。図5を見れば分かるように、遷移を選択すると、オブジェクトインスペクタでは、Guard(ガード条件)プロパティも指定できます。既に述べたように、ガードはOCL式として定義するので、プロパティエディタには、図6のようにOCL式エディタを使います。

図6 OCL式エディタ
また、ダイアグラム自身にも、「ステート属性」といったプロパティがあります。このプロパティは、ダイアグラムをOrderクラスに結び付けます。クラスダイアグラムに戻って、Orderクラスにステート属性と同じ名前の新しい属性が追加されており、これがステート属性としてオブジェクトインスペクタにマークされていることを確認してください。必要なら、OrderStateのようにこの属性の名称をデフォルトのState_1から変更することができます。
ビジネスロジックの定義が終わったら、次にECO空間(ECO Space)に移ります。ECO Spaceデザイナの下部のツールバーには、どのECOパッケージをアプリケーションで使用するかを指定するボタンがあります。ECOが設計およびランタイムの双方で、.NETリフレクション技術を活用している点を覚えておいてください。ECOアプリケーションを開発するときには、特定の間隔でプロジェクトをコンパイルするとよいでしょう。これにより、最新の情報がECOデザイナに提供されます。

図7 「ECO Spaceに使うパッケージの選択」ダイアログ
このサンプルでは、永続化ストレージを使用することはしません。ECOアプリケーションをデータベースに関連付け、オブジェクトリレーションマッピングを設定する方法については、他のBDN記事を参照してください。
最速のプロトタイピング手法
では、作成したビジネスロジックを検証する最も速い方法は何でしょうか?ECOアプリケーションを開発しているときに、ECOパッケージのテストには、ECOデバッガが極めて有用であることが分かります。プロジェクトに追加されたWinFormのUIデザイナを表示してください。ここで、フォーム上にボタン(TButton)を配置し、オブジェクトインスペクタで、「ECOGlobalActionsのEcoAction」プロパティを選択します。ここで、ドロップダウンリストから、[ShowDebugger]を選択します。ボタンのキャプションは、この変更を反映します。ECO内部を検査するためには、恐らくExpressionHandleを追加したり、ReferenceHandleのECOspaceTypeプロパティなどを指定しようすると思いますが、これは必要ないようです。サンプルを実行すると、デバッガは、すでにECO Spaceへのハンドルを保持しています。では、[F9]キーを押して、サンプルアプリケーションを実行してみましょう。フォームが表示されたら、ボタンをクリックしてECOデバッガを有効にします。すると、図8のように表示されます。

図8 ECOデバッガ
ここで、デバッガを使ってアプリケーションを検査します。先に述べたように、この機能は大変有用ですから、ぜひその操作に慣れてください。ステートマシンをすばやく検査するために、Orderクラスを選択してこれをダブルクリックします。これにより、[Add]ボタンが利用可能になります。[Add]をクリックして、Orderクラスのインスタンスを作成してください。

図9 ECOデバッガ
デバッガでは、生成したインスタンスの行をダブルクリックすることで、図10のようなEco AutoFormを開くことができます。フォームは、オブジェクトのプロパティ、現在の状態(ステート)と他の状態に遷移させるトリガーを表示します。

図10 Orderクラスを表示したECO AutoForm
可能性のある遷移に対するガードが「偽」の時には、対応するボタンは無効になります。もう一度、ステートマシンダイアグラムのガードの定義を見てください。これをテストするには、Unitsを10に、Priceを50に変更します。現在、注文の合計(Total)は500です。これで、図11のように、”Approved”の状態には遷移することができなくなりました。

図11 Orderクラスを表示したECO AutoForm
まとめ
ここで示した例は非常に簡単ですが、ステートマシンが、アプリケーションの抽象化レベルを上げることに貢献していることを理解できたと思います。ステートマシンは、ECOアプリケーションフレームワークを強力に拡張するものです。今後の記事では、ステートマシンを使った、より高度なトピックを探求していこうと思います。