另一个应用程序体系结构问题
本文关键字:问题 程序体系结构 应用 另一个 | 更新日期: 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功能没有多大意义,我会在域服务层创建另一个服务,将其命名为UsersManagerService
或UsersDomainService
最后,如果要实现存储库模式,请考虑通用存储库。