与服务层或域对象本身的接口? (DDD)
-
29-09-2019 - |
题
我仍在学习DDD,我有这两个(可能很简单)的问题:
如果一个 工厂 创建新对象/图形/总计的 实例,也 “重构” 来自 存储库, , 然后:
(1)您的服务层是否在实体实例或域服务函数上函数/工作/工作单位调用或行为方法?我因这些组件的责任而迷失了电话堆栈。
(2)实体实例是否具有上述“行为方法”?例如,帖子有 p.UpdatePost(string bodyText)
还是不是域模型的关注点,因此存储库应该实现同样的问题?或服务层函数,在这种情况下,它应该调用存储库,而实体实例仅具有特定于域而不是持久性的行为方法?但是,为什么当用户的目标是“更新帖子”是一个域函数?
您可以看到我到处都是。请帮忙。
解决方案
(1)您的服务层是否在实体实例或域服务函数上函数/工作/工作单位调用或行为方法?我因这些组件的责任而迷失了电话堆栈。
通常 - 最高级别检索必要的聚合根并在其上调用功能。有时,最高级别会检索多个骨料根并将其传递到域服务,但并不经常是因为域服务是一个很强的迹象,表明没有识别的骨料根。最终 - 最高级别可确保始终存在聚合根。
(2)实体实例是否具有上述“行为方法”?例如,帖子是否具有p.updatepost(字符串BodyText),或者不是域模型的关注点,因此可以使用存储库来实现同样的问题?或服务层函数,在这种情况下,它应该调用存储库,而实体实例仅具有特定于域而不是持久性的行为方法?但是,为什么当用户的目标是“更新帖子”是一个域函数?
是的,他们做到了。域模型应意识到其状态的变化。起初看起来更有益。很棒的是,您获得了可扩展的点。如果客户以后一周会走路并说他希望系统在用户更新发布时检查其他内容 - 而不是搜索的每一行 post.bodyText="new value"
, ,您将能够直接去 post.UpdatePost
方法并将必要的东西附加在那里。
另一方面 - CRUD并非与域驱动的设计相互排斥。例如 - 在我的应用程序中,对用户及其角色的管理不足以使我什至没有尝试对其进行详细建模。您需要识别您的应用程序所描述和合作的业务中重要的部分。
请记住,域驱动的设计仅对复杂的应用程序有意义。简单的博客应用程序不需要它。
(3)我假设服务层(不是域服务)应该封装接口与域层的交互方式时,我是错误的吗?
如我所见,应用程序更多用于协调基础架构。如果没有涉及基础架构 - 然后应用程序服务 失去价值:
应用程序服务基本上只是立面。如果复杂性增加了它解决的超重问题,则每个立面都很糟糕。
内部域:
//aggregate root is persistence ignorant.
//it shouldn't reference repository directly
public class Customer{
public string Name {get; private set;}
public static Customer Register(string name){
return new Customer(name);
}
protected Customer(string name){
//here it's aware of state changes.
//aggregate root changes it's own state
//instead of having state changed from outside
//through public properties
this.Name=name;
}
}
//domain model contains abstraction of persistence
public interface ICustomerRepository{
void Save(Customer customer);
}
在域外:
public class CustomerRepository:ICustomerRepository{
//here we actually save state of customer into database/cloud/xml/whatever
public void Save(Customer customer){
//note that we do not change state of customer, we just persist it here
_voodoo.StoreItSomehow(customer);
}
}
//asp.net mvc controller
public class CustomerController{
public CustomerController(ICustomerRepository repository){
if (repository==null)throw new ArgumentNullException();
_repository=repository;
}
public ActionResult Register(string name){
var customer=Customer.Register(name);
_repository.Save(customer);
}
}