7

さまざまな理由から、新しいビジネスオブジェクト/データストレージライブラリを作成しています。このレイヤーの要件の1つは、ビジネスルールのロジックと実際のデータストレージレイヤーを分離することです。

同じオブジェクトへのアクセスを実装する複数のデータストレージレイヤーを持つことができます。たとえば、ほとんどのオブジェクトを実装するメインの「データベース」データストレージソースと、ユーザーオブジェクトを実装する別の「ldap」ソースです。このシナリオでは、ユーザーはオプションでLDAPソースから取得できますが、機能がわずかに異なる場合があります(たとえば、ユーザーオブジェクトを保存/更新することはできません)が、それ以外の場合は、アプリケーションで同じように使用されます。別のデータストレージタイプは、Webサービスまたは外部データベースである可能性があります。

これを実装するために私たちが検討している主な方法は2つあり、私と同僚は基本的なレベルで意見が一致していません。どちらを使用するのが最適かについてアドバイスをお願いします。ここでいくつかの客観的な視点を探しているので、それぞれの説明をできるだけ中立に保つようにします。

  • ビジネスオブジェクトは基本クラスであり、データストレージオブジェクトはビジネスオブジェクトを継承します。クライアントコードは、データストレージオブジェクトを処理します。

    この場合、共通のビジネスルールは各データストレージオブジェクトに継承され、クライアントコードによって直接使用されるのはデータストレージオブジェクトです。

    これは、クライアントコードが特定のオブジェクトに使用するデータストレージメソッドを決定することを意味します。これは、そのタイプのオブジェクトに対してインスタンスを明示的に宣言する必要があるためです。クライアントコードは、使用している各データストレージタイプの接続情報を明示的に知る必要があります。

    データストレージレイヤーが特定のオブジェクトに異なる機能を実装している場合、オブジェクトの外観が異なるため、クライアントコードはコンパイル時にそれを明示的に認識します。データの保存方法を変更した場合は、クライアントコードを更新する必要があります。

  • ビジネスオブジェクトは、データストレージオブジェクトをカプセル化します。

    この場合、ビジネスオブジェクトはクライアントアプリケーションによって直接使用されます。クライアントアプリケーションは、基本接続情報をビジネスレイヤーに渡します。特定のオブジェクトが使用するデータストレージ方法の決定は、ビジネスオブジェクトコードによって行われます。接続情報は、構成ファイル(クライアントアプリは実際にはその詳細を認識/認識していません)から取得したデータのチャンクであり、データベースの単一の接続文字列、またはさまざまなデータストレージタイプの複数の接続文字列である可能性があります。追加のデータストレージ接続タイプは、別の場所から読み取ることもできます。たとえば、さまざまなWebサービスへのURLを指定するデータベースの構成テーブルです。

    ここでの利点は、新しいデータストレージメソッドが既存のオブジェクトに追加された場合、実行時に構成設定を設定して使用するメソッドを決定でき、クライアントアプリケーションに対して完全に透過的であることです。特定のオブジェクトのデータストレージ方法が変更された場合、クライアントアプリを変更する必要はありません。

  • ビジネスオブジェクトは基本クラスであり、データソースオブジェクトはビジネスオブジェクトから継承します。クライアントコードは主に基本クラスを扱います。

    これは最初のメソッドに似ていますが、クライアントコードは基本ビジネスオブジェクトタイプの変数を宣言し、ビジネスオブジェクトのLoad()/ Create()/etc静的メソッドは適切なデータソースタイプのオブジェクトを返します。

    このソリューションのアーキテクチャは最初の方法と似ていますが、主な違いは、特定のビジネスオブジェクトに使用するデータストレージオブジェクトが、クライアントコードではなく、ビジネスレイヤーによって行われるかどうかの決定です。

この機能の一部を提供する既存のORMライブラリがすでに存在することは知っていますが、今のところそれらを割り引いてください(データストレージレイヤーがこれらのORMライブラリの1つで実装されている可能性があります)-また、意図的に言っていないことに注意してくださいここで使用されている言語は、強く入力されていること以外は何ですか。

ここでは、どの方法を使用するのが良いか(または他の方法を自由に提案するか)、およびその理由について、いくつかの一般的なアドバイスを探しています。

4

7 に答える 7

11

おそらくより良いデカップリングを備えた別の代替案を提案するかもしれません。ビジネスオブジェクトはデータオブジェクトを使用し、データオブジェクトはストレージオブジェクトを実装します。これにより、ビジネスオブジェクトのビジネスルールが維持されますが、ストレージソースや形式に依存することなく、データオブジェクトは、ストレージオブジェクトの動的な変更(オンライン/オフライン操作など)など、必要な操作をサポートできます。

これは上記の2番目のカテゴリに分類されます(ビジネスオブジェクトはデータストレージオブジェクトをカプセル化します)が、データセマンティクスをストレージメカニズムからより明確に分離します

于 2008-09-23T03:36:56.500 に答える
1

また、クライアントから離れてビジネスに直接電話をかけるためのファサードを持つこともできます。また、ビジネスへの共通のエントリポイントを作成します。

述べたように、あなたのビジネスはあなたのDTOとファサード以外のものにさらされるべきではありません。

はい。クライアントはDTOを処理できます。これは、アプリケーションを介してデータを渡すための理想的な方法です。

于 2008-09-23T03:50:27.013 に答える
1

私は一般的に、「ビジネスオブジェクトがデータオブジェクト/ストレージをカプセル化する」を最も好みます。ただし、要するに、データ オブジェクトとビジネス オブジェクトの冗長性が高く、価値がないと思われる場合があります。これは、データ アクセス レイヤー (DAL) の基礎として ORM を選択した場合に特に当てはまります。しかし、長期的に見れば、真の成果が得られるのはアプリケーションのライフサイクルです。図示されているように、特にクラウド コンピューティングの出現により、分散システムでよくあることですが、「データ」が 1 つまたは複数のストレージ サブシステム (RDBMS に限定されない) から来ることは珍しくありません。たとえば、Restful サービスからのデータ、RDBMS からの別のチャンクまたはオブジェクト、XML ファイルや LDAP からの別のデータなどがある場合があります。この気づきにより、これは、ビジネスからのデータ アクセスを非常に適切にカプセル化することが重要であることを意味します。c-tors とプロパティを介して公開 (DI) する依存関係にも注意してください。

とはいえ、私が試行錯誤してきたアプローチは、アーキテクチャの「肉」をビジネス コントローラに配置することです。現代のデータ アクセスを従来の考え方よりもリソースと考えて、コントローラーは URI またはその他の形式のメタデータを受け入れます。これを使用して、ビジネス オブジェクトに対して管理する必要があるデータ リソースを知ることができます。次に、ビジネス オブジェクト自体はデータ アクセスをカプセル化しません。むしろコントローラーが行います。これにより、ビジネス オブジェクトを軽量かつ具体的に保ち、コントローラーが最適化、構成可能性、トランザクション環境などを提供できるようになります。コントローラーは、多くの ORM のコントローラー部分と同様に、ビジネス オブジェクト コレクションを「ホスト」することに注意してください。

さらに、ビジネス ルールの管理も検討してください。UML (または、私のように頭の中のモデル :D ) に目を細めると、ビジネス ルール モデルが実際には別のモデルであり、場合によっては永続的であることに気付くでしょう (たとえば、ビジネス ルール エンジンを使用している場合)。 . ビジネス コントローラーにもルール サブシステムを実際に制御させ、ビジネス オブジェクトがコントローラーを介してルールを参照できるようにすることを検討します。その理由は、必然的に、有効性を判断するために、ルールの実装でルックアップとクロスチェックを実行する必要があるためです。多くの場合、ハイドレートされたビジネス オブジェクト ルックアップとバックエンド データベース ルックアップの両方が必要になる場合があります。たとえば、「新しい」エンティティのみがハイドレートされている場合など、重複エンティティの検出を検討してください。ルールをビジネス コントローラーに管理させ、

擬似コード:

using(MyConcreteBusinessContext ctx = new MyConcreteBusinessContext("datares://model1?DataSource=myserver;Catalog=mydatabase;Trusted_Connection=True ruleres://someruleresource?type=StaticRules&handler=My.Org.Business.Model.RuleManager")) {

User user = ctx.GetUserById("SZE543");
user.IsLogonActive = false;
ctx.Save();
}

//a business object
class User : BusinessBase {
  public User(BusinessContext ctx) : base(ctx) {}

  public bool Validate() {
    IValidator v = ctx.GetValidator(this);
    return v.Validate();
  }
}

// a validator
class UserValidator : BaseValidator, IValidator {
 User userInstance;
 public UserValidator(User user) {
  userInstance = user;
 }

 public bool Validate() {
   // actual validation code here
   return true;
 }
}
于 2010-05-22T00:03:05.003 に答える
0

クライアントは、ストレージオブジェクトを直接処理しないでください。これらはDTOを直接処理できますが、ビジネスオブジェクトにラップされていないストレージのロジックを持つオブジェクトは、クライアントから直接呼び出されるべきではありません。

于 2008-09-23T03:44:28.230 に答える
0

CLSAは長い間存在しています。しかし、私はEricEvansの本http://dddcommunity.org/で説明されているアプローチが好きです。

于 2008-09-23T05:09:38.337 に答える
0

Rocky Lhotka による CSLA.net をチェックしてください。

于 2008-09-23T03:58:31.657 に答える
0

さて、グレッグが言っていた同僚です。

Greg は、私たちが検討してきた代替案を非常に正確に説明してくれました。状況の説明にいくつかの考慮事項を追加したいだけです。

クライアント コードは、ビジネス オブジェクトが格納されているデータ ストレージを認識しない可能性があります。ただし、データ ストレージが 1 つしかない場合、または同じビジネス オブジェクト タイプ (ローカル データベースと外部 LDAP に格納されているユーザー) に対して複数のデータ ストレージがある場合に発生する可能性がありますが、クライアントはこれらのビジネス オブジェクトを作成しません。システム分析の観点から言えば、同じタイプのオブジェクトの 2 つのデータストレージの存在がユース ケース フローに影響を与える可能性があるユース ケースがあってはならないことを意味します。

異なるデータ ストレージで作成されたオブジェクトを区別する必要が生じるとすぐに、クライアント コンポーネントは、そのユニバース内のデータ ストレージの多様性を認識する必要があり、オブジェクトの作成時にどのデータ ストレージを使用するかを決定する責任を負わなければなりません。 (そして、データストレージからのオブジェクトのロードだと思います)。ビジネス層は、この決定を行っているふりをすることができますが、意思決定のアルゴリズムは、クライアント コンポーネントからの情報の種類と内容に基づいており、クライアントが意思決定に対して事実上責任を負います。

この責任は、さまざまな方法で実装できます。各データ ストレージの特定のタイプの接続オブジェクトにすることができます。新しい BO インスタンスなどを作成するために呼び出すメソッドを分離することができます。

よろしく、

マイケル

于 2008-09-23T13:50:52.250 に答える