私はいくつかの 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 エンティティ + 永続性のものと似ています。
さて、これについてどう思いますか?