3

私はビジネスオブジェクトでこのような例をよく見ました:

public void Save()
{
     if(this.id > 0)
     {
          ThingyRepository.UpdateThingy(this);
     }
     else
     {
          int id = 0;
          ThingyRepository.AddThingy(this, out id);
          this.id = id;
     }
}

では、なぜここで、ビジネスオブジェクトについてですか?これは、ビジネスロジックよりも、コンテキストまたはデータに関連しているように見えます。

たとえば、このオブジェクトのコンシューマーは、次のようなことを経験する可能性があります...

...Get form values from a web app...

Thingy thingy = Thingy.CreateNew(Form["name"].Value, Form["gadget"].Value, Form["process"].Value);
thingy.Save();

または、更新のためにこのようなもの...

... Get form values from a web app...

Thingy thingy = Thingy.GetThingyByID(Int32.Parse(Form["id"].Value));
Thingy.Name = Form["name"].Value;
Thingy.Save();

では、これはなぜですか?計算やビジネス固有のルールなどの実際のビジネスロジックを含めて、取得/永続化を避けてはどうでしょうか。

このアプローチを使用すると、コードは次のようになります。

... Get form values from a web app...

Thingy thingy = Thingy.CreateNew(Form["name"].Value, Form["gadget"].Value, Form["process"].Value);
ThingyRepository.AddThingy(ref thingy, out id);

または、更新のためにこのようなもの...

... get form values from a web app ...

Thingy thingy = ThingyRepository.GetThingyByID(Int32.Parse(Form["id"].Value));
thingy.Name = Form["Name"].Value;
ThingyRepository.UpdateThingy(ref thingy);

これらの例の両方で、オブジェクトに対して何が行われているのかを最もよく知っているコンシューマーは、リポジトリーを呼び出し、ADDまたはUPDATEのいずれかを要求します。オブジェクトはそのコンテキストではDUMBのままですが、オブジェクトの取得方法や永続化方法ではなく、オブジェクト自体に関連するコアビジネスロジックを提供します。

つまり、GETメソッドとSAVEメソッドをビジネスオブジェクト自体に統合することのメリットはわかりません。

不平を言って従うのをやめるべきですか、それとも何かが足りないのですか?

4

4 に答える 4

4

これはActive Record パターンにつながります( EAA の P 160 ページを参照)。

個人的に私はファンではありません。永続化メカニズムを変更するにはビジネス オブジェクトの変更が必要になるように、ビジネス オブジェクトと永続化メカニズムを緊密に結合しますか? データ層とドメイン層を混在させますか? 単一責任の原則に違反していますか? 私のビジネスオブジェクトがAccountインスタンスメソッドを持っている場合Account.Save、アカウントを見つけるには静的メソッドを持っていますAccount.Findか? ラッキー。

とは言っても、それには用途があります。オブジェクトがデータベース スキーマに直接準拠し、ドメイン ロジックが単純で、テストの容易さ、リファクタリング、依存関係の挿入、オープン/クローズ、懸念事項の分離などに関心がない小規模なプロジェクトの場合、これは適切な選択です。

于 2009-07-29T13:59:09.790 に答える
2

ドメイン オブジェクトには、永続性の問題への参照があってはなりません。

永続化サービスを表すリポジトリ インターフェイスをドメイン内に作成し、それをドメイン外に実装します (別のアセンブリに実装できます)。

この方法では、集約ルートはリポジトリを参照する必要がなく (これは集約ルートであるため、必要なものはすべて既に存在しているはずです)、依存関係や永続性の問題がなくなります。したがって、テストが容易になり、ドメインに焦点が当てられます。

于 2009-07-29T13:36:08.017 に答える
0

私はDDDについて理解していませんが、1つの方法があることは理にかなっています(UPSERTを実行します。レコードが存在しない場合は挿入し、そうでない場合は更新します)。

クラスのユーザーは、ダムのように振る舞い、既存のレコードで[保存]を呼び出し、新しいレコードで[更新]を呼び出すことができます。1つのアクションポイントを持つことははるかに明確です。

編集:INSERTを実行するかUPDATEを実行するかの決定は、リポジトリに任せたほうがよいでしょう。ユーザーはRepository.Save(....)を呼び出すことができます。これにより、新しいレコード(レコードがまだDBにない場合)または更新が発生する可能性があります。

于 2009-07-29T04:29:13.680 に答える
0

彼らのアプローチが気に入らない場合は、独自のものを作成してください。個人的には、ビジネス オブジェクトの Save() インスタンス メソッドは本当にいい匂いがします。覚える必要のあるクラス名が 1 つ減りました。ただし、ファクトリーセーブには問題はありませんが、両方を持つことがなぜそれほど難しいのかわかりません。IE

class myObject
{
   public Save()
   {
      myObjFactory.Save(this);
   }
}
...

class myObjectFactory
{
   public void Save(myObject obj)
   {
      // Upsert myObject   
   }
}
于 2009-07-29T04:45:13.413 に答える