42

私は、エディターとプロジェクトの概念を持つドメインモデルを持っています。

編集者は多数のプロジェクトを所有しており、プロジェクトには編集者の所有者だけでなく、多数の編集者メンバーもいます。したがって、編集者には多数の「参加」プロジェクトもあります。

私はこれをモデル化し、永続性のためにリポジトリパターンを使用するためにDDDアプローチを採用しています。しかし、私はまだパターンを十分に理解していないので、これをどのように行うべきかを判断できません。

私は、エディターとプロジェクトが潜在的に同じ集合体であり、ルートがエディターであるという前提で作業しています。したがって、エディターを取得してそのプロジェクトを列挙し、そこからプロジェクトのメンバーのエディターを列挙することができます。

ただし、リポジトリからのエディタの取得のみが許可されている場合、それを所有するエディタを取得するときに、リポジトリからすべてのプロジェクトをロードする必要があるということではありませんか?また、メンバーのエディターを遅延ロードする場合、プロジェクトにはリポジトリへの参照も必要ですか?

または、アグリゲートを分割してエディターリポジトリとプロジェクトリポジトリがある場合、新しいプロジェクトがエディターに追加されたときなど、2つの間でトランザクションをどのように処理する必要がありますか?例えば:

Editor e = new Editor("Editor Name");
editorRepository.Add(e);

Project p = e.CreateProject("Project Name");
projectRepository.Add(p);    // These two lines
editorRepository.Save(e);    // should be atomic

リポジトリパターンの意図を誤解していますか?

4

4 に答える 4

30

リポジトリ パターンの意図を誤解していますか?

私は「ええ」と言うつもりですが、私と私が一緒に働いたすべての人が同じ理由で同じことを尋ねたことを知っておいてください... 「あなたは4次元で考えていません、マーティ」.

少し単純化して、最初に Create メソッドの代わりにコンストラクターを使いましょう。

Editor e = new Editor("Editor Name");
e = editorRepository.Add(e);

Project p = new Project("Project Name", e);
p = projectRepository.Add(p);

その下で、プロジェクト リポジトリは常に有効な所有者 ( p.EditorId) を作成時にプロジェクト データに格納していますが、編集者のプロジェクトを再設定しても、そこに存在します。これが、必要なすべてのプロパティをコンストラクターに入れることをお勧めする理由です。オブジェクト全体を渡したくない場合は、e.Id意志だけで十分です。

また、メンバーのエディターを遅延ロードしたい場合、プロジェクトにはリポジトリへの参照も必要ですか?

さて、エディターのプロジェクトをオンデマンドで再設定する方法については、目的に応じていくつかの選択肢があります。Straight Repository はあなたが欲しいと言います:

IEnumerable<Project> list = projectRepository.GetAllProjects()
                                .Where(x => x.editorId == e.Id);

しかし、どこに置くのですか?Project や Editor の中ではありません。その通りです。そうしないと、リポジトリにアクセスする必要があり、それは良くありません。上記のスニペットは疎結合ですが、単独では再利用できません。リポジトリ パターンの限界に達しました。

次はアプリケーションのアダプタ層で、リポジトリの共有ソースStaticServiceWrapper(必要なすべてのリポジトリを流暢に。実稼働システムでこの方法を正確に行ったことはありませんが、簡潔な例を示します。

public static class Aggregators
{
    // one to one, easy
    public static Editor GetOwner(this Project p)
    {
        return StaticServiceWrapper.editorRep.GetEditorById(p.editorId);
    }

    // one to many, medium
    public static IEnumerable<Project> GetProjects(this Editor e) 
    { 
        return StaticServiceWrapper.projectRep.GetAllProjects()
                .Where(x => x.editorId == e.Id);
    }

    // many to many, harder
    public static IEnumerable<Editor> GetMembers(this Project p)
    {
        var list = StaticServiceWrapper.projectMemberMap.GetAllMemberMaps()
                        .Where(x => x.projectId == p.projectId);

        foreach ( var item in list )
            yield return StaticServiceWrapper.editorRep.GetEditorById(item.editorId);
    }
}

基本的に、GetAll、GetById、Add、Update、Remove オブジェクト リポジトリが完了したら、関連付けをそのままにして、オブジェクト/レイヤー階層を上に移動して、アダプターやキャッシュ、ビジネス ロジックなどの楽しい部分に移動する必要があります ( 「ああ、私の!」)。

于 2009-05-14T04:40:20.537 に答える
5

責任を EditorOwner と EditorMember に分割するのはどうですか?

あなたのドメインを知らなくても、私は彼らが異なる責任を持っていると想像します. EditorMember オブジェクトはかなり軽いかもしれません。

これらのドメイン オブジェクトもユーザーに関連している可能性がありますが、それは別のコンテキストになります。

それは物事を助けますか、それとも単に複雑にしますか?

于 2009-01-23T04:55:44.373 に答える
3

アプリケーションのニーズによって異なります。特定のエディタのすべてのプロジェクトをロードすることが大きな問題である場合は、仮想プロキシのような遅延ロード パターンを試してください。

プロジェクトのメンバー エディターの遅延読み込みに関しては、仮想プロキシを使用している場合、プロキシがドメインの一部であるとは考えていないため、EditorRepository を使用してプロキシを挿入しても問題はありません。

Aggregate を分割すると、原子性に対する 1 つの解決策としてUnit of Workパターンを調べることができます。ただし、この問題は DDD に固有のものではなく、トランザクション動作に対する他の解決策があると確信しています。

于 2009-01-23T02:45:29.643 に答える
0

ここでは、所有権用とメンバーシップ用の 2 つの異なる関係があります。

所有関係は単純な 1 対多 (プロジェクトごとに 1 人の所有者) です。メンバーシップの関係は多対多です (プロジェクトごとに多くの編集者、編集者ごとに多くのプロジェクト)。

Project クラスで Owner プロパティを提供し、ProjectRepository でメソッドを提供して、特定のエディターが所有するすべてのプロジェクトを取得できます。

Many リレーションシップの場合、Project クラスに Members プロパティを提供し、ProjectRepository にメソッドを提供して、指定された Editor をメンバーとして含むすべてのプロジェクトを取得します。

また、エディターとプロジェクトはエンティティのようです。おそらく集計を分割しますが、おそらくこれらの用語は、集計のサブエンティティにするコンテキストで特定の意味を持っています。

于 2009-02-11T13:01:07.957 に答える