3

私はいくつかの DDD を試しています。私が行ったことを最も簡単な方法で説明しようと思います。

コア プロジェクト
コア プロジェクトには、エンティティ、VO、およびドメイン サービスが含まれます。たとえば、UserエンティティとUserRelationエンティティがあります。Userエンティティとは何かは誰もが知っていると思います。UserRelationには、フォローや接続 (双方向フォロー) など、ユーザーが互いにどのように接続されているかに関する情報が含まれています。そのため、Follow(user,user) や Connect(user, user) などのステートレス メソッドを備えたUserDomainServiceがあります。

public class User
{
    public string Name { get; set; }
    public string Username { get; set; }

    public void ChangeUsername(stirng newUsername)
    {
        ApplyEvent(new UserUsernameChanged(newUsername));
    }
}

public class UserRelation
{
    ctor(User1, User2, isBidirectional)
    public User User1 { get; set; }
    public User User2 { get; set; }
    public bool IsBidirectional { get; set; }
}

public class UserDomainService
{
    public UserRelation Follow(User user1, User user2)
    { 
        return new UserRelation(user1,user2,false);
    }
}

リポジトリ プロジェクト

私はNHibernateを使用しているので、そのようなプロジェクトを作成しないことにしました。代わりに、NHibernate を直接使用しています。たとえば、私の UI では、DB からユーザー オブジェクトを取得し、それを変更してから、session.Save(user) を呼び出します。

問題

次のような操作を行いたい場合は、次のようにします。

  • DBから情報を取得する
  • サービスから Follow(user1, user2) を呼び出します
  • UserRelation オブジェクトを DB に保存 最終的に、アプリケーション コードは少し複雑になります。このコードを 2 ~ 3 か所で使用し、ある時点でリファクタリングする必要があるとします。

私の解決策
私の解決策は、汚い仕事をして消費者にエンティティとドメインサービスを直接使用する代わりにApplicationServiceを使用させるApplicationServiceプロジェクトを作成することです

public class UserApplicationService
{
    ctor(UserDomainService userDomainService){}

    User GetUser(Guid id)
    {
        return NhibernateSession.Get(id)
    }

    public void Follow(Guid user1Id, Guid user2Id)
    {
        var u1 = GetUser(user1Id);
        var u2 = GetUser(user2Id);
        var userRelation = _userDomainService.Follow(u1,u2);
        NhibernateSession.Save(userRelation);
    }

    public void ChangeUsername(Guid user, string newUsername)
    {
        user.ChangeUsername(newUsername);
        NhibernateSession.Save(user);
    }
}

このアプリケーション サービスは良いですか、それとも悪いですか。ご覧のとおり、新しいサービスはリポジトリとしても機能するため、UserRepository クラスを作成できますが、ここでは省略します。気になるのは、2 つのメソッドのパラメーターです。それらは Guid を受け入れ、サービスは DB からユーザーを取得します。もう 1 つのオプションは、User オブジェクトを直接渡すことです。ChangeUsername メソッドは、User エンティティ + 永続性のものと似ています。

さて、これについてどう思いますか?

4

2 に答える 2

1

個人的には何も問題はないと思います。実際、これは私が一緒に働いている会社が行った方法です。そのサービスからデータアクセスを抽象化する限り、データレイヤー間のメディエーターとしてビジネスレイヤーの一部になる可能性があります。 ui レイヤーを使用すると、同じことを繰り返したり、特定の操作に対して概説されているルールが確実に実行されるようにしたりする必要がなくなります。

于 2011-07-21T10:01:39.907 に答える
1

私の2セント。

DDD は適用可能であり、大規模なプロジェクトに適しています。かっこいいからといってプロジェクトに適用するべきではありません。NHibernateSession を見ると、ID でユーザーを取得できることがわかります。NHibernateSession がそれを担当している場合、他にどのドメイン オブジェクトがありますか? リポジトリがないのに、なぜ DDD の過熱を強制するのですか?

OK、大きなドメインを持っていることを考えると、Follow機能をホストするために新しいプロジェクトを作成する理由が明確ではありません (入力 GUID に問題はありません)。IMOアプリケーション サービスレイヤーはエンティティとインフラストラクチャを処理するべきではありません。アプリケーション サービス層は、一部のドメイン オブジェクトの機能ではなく、アプリケーション全体を担当します。_userDomainServiceあなたのケースにより関連性が高いと思われる があることに気付きました。フォロー機能をそこに移動してもあまり意味がない場合は、ドメイン サービス レイヤーで別のサービスを作成し、次のように呼び出しますUsersManagerServiceUsersDomainService

最後に、リポジトリ パターンを実装する場合は、汎用リポジトリを検討してください。

于 2011-07-21T10:13:57.433 に答える