7

オブジェクトに単一の責任がある場合、次のことを受け入れることができますか?

public class Person
{
   public string Name;
   public DateTime DateOfBirth;

   private IStorageService _storageService;

   public Person(IStorageService storageService)
   {
      _storageService = storageService
   }

   public void Save()
   {
        _storageService.Persist(this);
   }
}

つまり、提供されたコラボレーターを使用します (ドメイン モデルが貧血になるのを防ぐのにも役立ちます)。

または、次のようにする必要があります。

public class Person
{
   public string Name;
   public DateTime DateOfBirth;

   public Person()
   {
   }


}
public class StorageService
{
    public void Persist(Person p)
    {
    }
}
4

6 に答える 6

10

以下は許容できますか?

class Person {
Person(IStorageService) { } ...
void Save() { } ...
}

この依存関係は意味がありません。

特定のストレージ実装にバインドしないため、 aPersonをに強く結び付けるわけではありませんが、そのような依存関係は意味がないと主張します。Storage

動詞としてのメソッド

クラスのメソッドは、その型によって実行される動詞と考えてください。そのタイプのインスタンスに、そのローカル ドメインに関して「何かをする」ように指示しています。

私が人として、 とはどういう意味Saveですか?

  • 保険会社を切り替えて、コストを最大 15% 削減しましたか?
  • 私は贖罪の神ですか?
  • 私の魂をオートマトンにダウンロードしましたか?

ストレージ サービスは可能であり、すべきSaveです。人々はできないSaveし、できることを宣伝すべきではありません。

靴べらにしようとしている

SaveToもっと理にかなっているかもしれません-つまりpublic void SaveTo(IStorageService storage)

しかし、あなたは人が自分自身をストレージに保存する方法を知る責任があると言っています. 私の意見では、これはSRP の違反ですまた、Domain Analysis の欠落部分も示しています。

のドメインには、Person保存、保管などに関するものは何も含まれません。ドメインのそのレベルでの人と他のものとの相互作用が含まれます。データ永続性のドメインは、Saveメソッドにとってより適切な場所です。

Person問題領域 (その抽象化レベル) にある場合はStorage、ソリューション領域にあります。

ロジックをどのように分離する必要があるか

ここには 3 つのロジックがあります。

  1. Person-「人のこと」について知っている
  2. Storage- 特定のタイプのストレージと、それにアクセスする方法を知っている
  3. Storage of Person- 人が保管に専念する方法を知っている

上記の私のアドバイスに従って、私はPerson自立するために去ります。Storageただし、とのロジックを分離することも、Storage of Person組み合わせることもできます。

ORM が採用するアプローチは、3 つの概念すべてを分離することです。「オブジェクト リレーショナル マッピング」の「マッピング」は、「人のストレージ」がカプセル化されている場所です。

このアプローチにより、Storageストレージ構成の読み取り、ストレージへの接続、ストレージが高速であることの確認、別のストレージ方法の選択など、潜在的に複雑なジョブにロジックを集中させることができます。また、メイン ドメインのモデルへの依存関係が削除されるため、ストレージ コードを他のドメイン モデルで再利用されます。

于 2011-11-11T22:33:31.330 に答える
4

SRPの定義を注意深く読むと、責任の定義が変更の理由であることがわかります。

最初のバージョンには、変更する理由が 2 つあります。

  • 永続化 API の変更
  • 価値の形が変わる

したがって、2 番目のバージョンは SRP に準拠していますが、SRP には準拠していません。

于 2011-11-12T08:33:28.757 に答える
4

私は2番目のバージョンに固執します。単一の責任がある場合は、最初のバージョンを使用できます。しかし、私の考えでは、モデル オブジェクトとは別の永続化レイヤーを考えるのが好きです。

また、第2版を連載していただけると助かります。おそらく、IStorageService への参照を使用して最初のバージョンをシリアル化することはできません。

于 2011-11-11T21:22:47.307 に答える
0

ドメイン名前空間が完全でテストされているほど、アプリケーションの品質が向上することがわかりました。永続エンティティはドメイン モデルに属さないため、この 2 つを分離します。

于 2011-11-11T21:27:48.523 に答える
0

person がモデリングしているドメイン オブジェクトである場合、サービスをカプセル化することはお勧めしません。つまり、あなたのことはわかりませんが、私は人間であり、保管サービスはありません;)

貧血ドメイン モデルに関する懸念は、ドメイン オブジェクトが互いにどのように関係しているかに関する懸念だと思います。それらが単にリテラルのプロパティ バッグである場合、貧血です。あなたはおそらく、物事のモデル化や、いつ、どのように自分自身を維持するかを理解することに関心を持たせることで、これを改善したくないでしょう.

貧血ドメインの考慮事項は、豊富な相互作用を持つことで改善されます. たとえば、学校をモデル化している場合、Person は Student または Teacher のオブジェクトであり、Class は生徒と教師のコレクションです。次に、 myTeacher.Assign(Homework hw, Class class) などのある種の概念があります。これは、ドメイン エンティティがデータ アクセス 配管コードとどのように相互作用するかを「モデル化」するのではなく、ドメイン エンティティ間の実際の概念的な相互作用をモデル化することによって、ドメイン モデルを強化する方法です。

ちょうど私の2セント。

于 2011-11-11T22:11:01.420 に答える