3

我正在尝试一些 DDD,我将尝试以最简单的方式描述我所做的事情。

核心项目
核心项目包含实体、VO 和领域服务。例如,我有User实体和UserRelation实体。我想我们都知道什么是用户实体。UserRelation包含有关用户如何相互连接的信息,例如关注和连接(双向关注)。因此,我有带有无状态方法的UserDomainService,例如 Follow(user,user) 和 Connect(user, user)。

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 中,我从数据库中获取一个用户对象,对其进行更改,然后调用 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 类,但现在让我们跳过它。困扰我的是这两种方法中的参数。他们接受Guids,服务从数据库中检索用户。另一种选择是直接传递用户对象。ChangeUsername 方法类似于 User 实体 + 持久性中的方法。

那么,您对此有何看法?

4

2 回答 2

1

我个人看不出有什么问题,事实上我合作的公司就是这样做的,只要你从该服务中抽象出数据访问,它就可以成为业务层的一部分,作为数据层之间的中介和 ui 层,它使您免于重复自己并确保为某个操作概述的任何规则触发。

于 2011-07-21T10:01:39.907 回答
1

我的 2 美分。

DDD 适用于大型项目。你不应该仅仅因为它很酷就将它应用到项目中。通过查看 NHibernateSession 我看到您可以通过 id 获取用户。好吧,如果 NHibernateSession 负责您拥有哪些其他域对象?您没有存储库,为什么要强制 DDD 过热?

好的,继续前进,因为您有一个很大的域,我不清楚为什么要创建一个新项目来托管Follow功能(那里的输入 GUID 没有错)。IMO应用程序服务层不应该处理实体和 infrustrucure,因为对于这个人来说它似乎太低了。应用服务层负责整个应用程序,而不是某些领域对象的功能。我注意到您的_userDomainService情况似乎与您的情况更相关。如果将跟随功能移到那里没有多大意义,我将在域服务层创建另一个服务,将其称为UsersManagerServiceUsersDomainService

最后,如果您要实现存储库模式,请考虑通用存储库。

于 2011-07-21T10:13:57.433 回答