高度なカスタマイズ > サービスおよびインフラストラクチャのカスタマイズ > サーバーロジックの開発 > ビジネスデータタイプの実装
  
ビジネスデータタイプの実装
ビジネスデータタイプは、基本的に、問題が発生したドメイン内で明確に定義できる情報の断片の抽出を処理するエンティティオブジェクト (認識側) として特徴付けることができます。このためビジネスデータタイプは、制御オブジェクト (実行側) と同様に動作ではなく主にデータによって定義されます。ビジネスデータタイプの仕様のほとんどがその属性によるので、通常、このビジネス情報の実装はクラスの属性に焦点を置きます。
また、ビジネスデータタイプはエンティティオブジェクトであり、通常は制御オブジェクトよりも軽量なため、3 階層 (クライアント、サーバー、データベース) アーキテクチャ内のサーバーとアプリケーションの間で情報を効率的に転送できます。
ビジネス属性の初期化
ビジネスデータタイプ属性の初期化は、連動的にコードによって生成された初期化メソッドによって行われます。モデル化されたビジネスデータタイプにコンストラクタは生成されません。その代わり、各モデル化コンストラクタに対してファクトリが作成され、ファクトリ内でインスタンスが作成されます。その後、ファクトリに一致する署名を持つ初期化メソッドが起動します。
これらの初期化メソッドは最初のコード生成時には空白で、コードジェネレータが現時点では初期化する属性を仮定できないため、手動で実装する必要があります。デフォルトでは、これらのメソッドが実装されると、今後の使用のためにこれらのコードが保持されます。Java コンストラクタのチェーンを模倣するには、各初期化メソッドは常にほかの作業よりも先に親初期化メソッドを起動する必要があります。
ビジネス属性アクセッサ
属性は常に、JavaBean プロパティのように、ゲッターメソッドとセッターメソッドの 2 つのアクセッサを持つプライベートフィールドとして生成されます。ゲッターは、属性の値を返す引数のないメソッドとして生成されます。
セッターは、属性を引数の値に設定する、単一引数のメソッドとして生成されます。セッターが生成時に wt.util.WTPropertyVetoException throws 節を伴うかどうかは、属性が制約されているかどうかによって異なります。この例外は、java.beans.PropertyVetoException を拡張し、カスタマイズしたメッセージを可能にします。
メソッドの本体に "preserve=no" というフラグが付けられていることに注目してください。これは、メソッド内のコードを上書きするようにコードジェネレータに指示します。ゲッターとセッターは、このフラグを yes に設定することによって保持できますが、一般にはこれは推奨されません。別の方法としては、「Windchill」タブの GenerateAccessors プロパティを偽に設定して、コードジェネレータに属性のゲッターやセッターを生成しないように指示することもできます。
アクセッサメソッドのオーバーライド
通常、オーバーライドされたアクセッサは以下の動作を行います。
属性の検証 (例を参照)
Lazy 属性の初期化
計算された属性アクセス
以下は、アクセッサメソッドのオーバーライドの例です。
ビジネス属性の確認
ビジネスデータタイプ属性の確認は、2 つの異なるレベルで処理されます。最も簡単で完全なコード生成レベルは、セッターによって起動される制約された属性の検証メソッドとして実装されます。属性の設定を拒否するために使用されるメカニズムは、セッターから発生させることが可能な wt.util.WTPropertyVetoException です。属性が制約されていない場合、セッターは例外の発生機能なしに生成されます。
文字列または数値属性の限界を指定するプロパティは、LowerLimit と UpperLimit です。どちらの場合でも、提供される値は文字列または固定値として処理されます。つまり、検証メソッドは、指定された値をそれぞれ LowerLimit または UpperLimit プロパティでテストするために、Java の左不等演算子または右不等演算子を使用する if ステートメントとともに生成されるコードです。以下の例は、これらの 2 つのプロパティと自動的に生成される検証コードの使用方法を示しています。
これより一般的なレベルでは、wt.fc.WTObject から継承される "checkAttributes" メソッドをオーバーライドして実装することにより、1 つ以上の属性を検証できます。このメソッドは、オブジェクトが最初にデータベースに保存される前、およびそれが修正されるたびに呼び出されます。この場合、発生する例外は wt.fc.InvalidAttributeException で、wt.util.WTPropertyVetoException ではありません。
checkAttribute メソッドの実装
以下の例に示す checkAttributes メソッドは、このセクションのアクセッサメソッドのオーバーライドの例に示した setStatus メソッドの代わりに使用できます。このメソッドは、状態を 2 に設定すると、終了コメントが確実に提供されるようにします。
checkAttributes メソッドは PersistenceManager から呼び出され、データベースに保存する前にオブジェクトの状態が正しいことを確認します。以下に checkAttribute メソッドの実装の例を示します。
ビジネス属性の集合体
関連付けのすべてのレベルで構造化された属性 (第 1 クラスではない属性) は、構造化された属性を保存する第 1 クラスのオブジェクトと同じデータベーステーブルに配置されます。総計された属性は、マッピング可能なオブジェクトである必要があり、多重度にかかわらず平面構造としてデータベーステーブルに常駐します。テーブルの平面性は、3 階層アーキテクチャのデータベース階層がオブジェクト指向のデータベースではなく、リレーショナルであると仮定されているためです。
ただし、トップレベルの構造化された属性の多重度が 0..1 または 0..* で、必須であるというフラグが付いていない場合は、データベース内で Null にできます。ネステッド構造の属性は Null にならないため、この最上位レベルの構造化された属性がほかの構造化された属性を集める場合は注意が必要です。
ビジネス属性の永続性
ビジネス属性は、「Persistent」というフラグが付いている場合、第 1 クラスオブジェクトのデータベーステーブルで列として永続されます。そうでない場合は、これはメモリ内の属性としてのみ扱われ、データベーステーブルのコラムにマッピングされません。
ビジネス属性の派生
派生属性は、ゲッターまたはセッターとして厳密に生成されます。モデル化された派生属性の名前のついたフィールドはありません。通常、派生属性をモデル化する目的は、アクセス時に計算された値として動作させることです。派生属性の副作用の 1 つは、シリアル化可能でも外部化可能でもないことです。派生属性は、クラスの本体では実装の詳細説明になりますが、生成された Windchill の外部化メソッドはこの属性の存在を認識しません。つまり、オブジェクトのデータを読み書きする外部化メソッドは、実装ではなく、オブジェクトモデルの情報に基づいて生成されます。
派生属性を持つオブジェクトが別のマシンに転送された場合、または外部で保存や読み込みが行われた場合、このオブジェクトの派生属性は存在しません。オブジェクトがシリアル化または外部化された後、処理に派生属性が必要な実装では、属性を再派生するためにアクセッサが呼び出されない限りエラーを引き起すと考えられます。
ビジネスサービスの実装
ビジネスサービスは、ビジネスサービスの設計パターンに基づいて、基本的な動作と問題が発生したドメインの処理をまとめて行う一連の抽象として特徴付けることができます。ビジネスサービスの主要クラスは、ビジネスオブジェクトで処理を行う制御オブジェクト (実行側) として動作します。また、クッキーは、オブジェクトごとに状態やキー情報を保存するビジネスサービスによって維持されます。
クッキークラスは、ビジネスサービスによって管理されるインタフェースに集められます。たとえば、PersistInfo は永続可能インタフェースに集められるクッキークラスです。永続可能を実装するクラスはすべて PersistInfo も集めます。PersistenceManager ビジネスサービスは、createStamp や modifyStamp などの PersistInfo の属性を管理します。
ビジネスサービスの初期化
ビジネスサービスは、シングルトンとしてサーバーでのみ実行されるように設計されています。サーバーが起動すると、自動的に開始するサービスを判断するために wt.properties ファイルが読み込まれます。これらの指定されたサービスが構築されて静的に初期化され、サービスイベントが登録されてサービスが開始されます。wt.properties ファイルの wt.services.service エンティティによって指定された順序は、サービスが開始される順序を制御します。サービスの起動に管理アクセスが必要な場合は、新しい SessionContext を作成して現在のユーザーを管理者に設定する必要があります。サービスの起動処理の最後にセッションコンテキストをリセットすることも重要です。セッションコンテキストが常にリセットされるようにするには、finally 節で行います。
ビジネスサービス操作
ビジネスサービス操作は、ローカルまたはリモートで起動できます。リモートの起動を行うことができるのはクライアントだけです。ローカルの起動はクライアントとサーバーのどちらでも行えます。
ビジネスサービスの Helper 抽象には、ローカルに起動できるメソッドのみが含まれています。これらのメソッドは、一般に、サービスの cookie 情報へのアクセスに使用されます。処理を助けるその他のタイプのメソッドもヘルパーで実装されます。サービス抽象には、サーバーでローカルに起動でき、サービスが RemoteInterface としてステレオタイプ化されている場合にクライアントからリモートで起動できるメソッドが含まれています。ヘルパー内のサービスのこのステレオタイプ化と集合体を使用すると、すべての Public メソッドが使用できます。ビジネスサービスは、使用可能なすべての外部操作がヘルパーまたはサービスクラスを介して公開されるようにする必要があります。ほかのサービスによって使用されるユーティリティクラスのメソッド以外、ほかの操作はすべて内部でのみ使用可能です。
サーバーで実行されるビジネスサービス操作は、データベース作業を実行する必要がある場合があります。データベースの一貫性、サービスの独立、ほかのサービスとの緩やかな関係を維持するため、トランザクションブロックを使用してデータベースの変更を保護する必要があります。以下のコード例のセクションは、トランザクションブロックの実装方法のガイドラインです。
ビジネスサービスイベントの拒否
ビジネスサービスがシステム内で発生したイベントの通知を受け取った場合、そのイベントを拒否することもできます。この場合は、リスナーとして購読し、notifyVetoableEvent メソッドを実装します。リスナーは、イベントのデータを処理し、拒否を適用できるかどうかを判断する必要があります。適用できる場合、リスナーは適切な例外を発生させます。適用できない場合、リスナーは処理が必要とする作業を行い、イベントに続行を許可します。
ビジネスサービスの規則
適用可能であれば、オペレーションの機能の一貫性と正当性を保つために、ビジネスサービスは規則を実装します。ビジネスルールの 2 つの基本的な形式は、アクセス制御と問題が発生したドメインの一貫性です。
アクセス制御は、誰が何をどのような方法で操作できるかを指定します。ビジネスサービスでのアクセス制御の強制は、明示的に実装されます。ロックサービスでは、たとえば、オブジェクトがロックするように要求されると、サービスはロックしようとするプリンシパルに対してオブジェクトへの修正アクセスを確保します。このため、以下に示すようにオブジェクトのロックはデータベース内で永続できます。
問題が発生したドメインの一貫性の強制は、アクセス制御とは少し異なります。ビジネスサービス内で常に問題が発生したドメインの正しい動作を維持することが目的ですが、特にいくつかの要件を満たす必要がある場合があります。たとえば、バージョン制御では、チェックインされたオブジェクトは再びチェックアウトが可能になります。ただし、オブジェクトがすでにチェックアウトされている場合は、何らかの共有ルールか結合ルールがない限り再びチェックアウトすることはできません。
ビジネスサービス通信
ビジネスサービスは、同期 Java 呼び出しを介して直接またはイベントによって別のビジネスサービスと通信できます。別のサービスとの直接の peer-to-peer 通信は、すべての Windchill サービスでアクセス制御が実装される方法です。これは最も初歩的な通信手段です。
イベントに基づく通信は、サービス間のより高度な通信手段です。サービスによってイベントを登録でき、イベント開始時にリスナーは別のサービスのイベントを購読できます。サービスイベントが発生すると、購読したすべてのリスナーにイベントの発生が通知されます。イベントの通知とレスポンスは、同期的です。このため、これはサービスのメソッド呼び出しと同じですが、イベントを引き起こすサービスにはほかのどのサービスに通知されるのかわかりません。通知されたサービスの 1 つがイベントを拒否すると、その時点で通知されていないほかのサービスには報告されません。