另一个应用程序体系结构问题

本文关键字:问题 程序体系结构 应用 另一个 | 更新日期: 2023-09-27 18:03:04

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

核心项目


核心项目包含实体、VO和域服务。例如,我有User实体和UserRelation实体。我想我们都知道什么是User实体。UserRelation包含有关用户如何相互连接的信息,如follow和connect(双向follow)。因为我有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);
    }
}

Repository Project

我正在使用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类,但现在我们先跳过这个。困扰我的是这两个方法中的参数。它们接受Guids,服务从DB检索用户。另一种选择是直接传递User对象。ChangeUsername方法类似于User实体+持久性的方法。

嗯,你觉得这个怎么样?

另一个应用程序体系结构问题

我个人不认为有什么问题,事实上我所在的公司就是这么做的,只要你从服务中抽象出数据访问,它就可以作为业务层的一部分,作为数据层和ui层之间的中介,它可以避免你重复自己,并确保为特定操作概述的任何规则都是有效的。

我的两分钱

DDD适用于大型项目。你不应该仅仅因为它很酷就把它应用到项目中。通过查看nhibernatessession,我看到你可以通过id获取User。如果nhibernatessession负责这个还有哪些域对象?你没有存储库,为什么要强制DDD过热?

好吧,继续前进,因为你有一个大的域,我不清楚为什么你要创建一个新项目来托管Follow功能(输入guid没有错)。在我看来,应用服务(em)层不应该处理实体和基础设施,因为它对这个家伙来说似乎太底层了。应用程序服务层负责整个应用程序,而不是某些领域对象的功能。我注意到你有一个_userDomainService,这似乎与你的情况更相关。如果移动Follow功能没有多大意义,我会在域服务层创建另一个服务,将其命名为UsersManagerServiceUsersDomainService

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