DDD:更新实体多个属性的指南
DDD: guidance on updating multiple properties of entities
所以,我决定学习 DDD,因为它似乎可以解决我一直面临的一些架构问题。虽然有很多视频和示例博客,但我还没有遇到指导我解决以下情况的视频和示例博客:
假设我有实体
public class EventOrganizer : IEntity
{
public Guid Id { get; }
public string Name { get; }
public PhoneNumber PrimaryPhone { get; }
public PhoneNumber AlternatePhone { get; private set; }
public Email Email { get; private set; }
public EventOrganizer(string name, PhoneNumber primaryPhoneNr)
{
#region validations
if (primaryPhoneNr == null) throw new ArgumentNullException(nameof(primaryPhoneNr));
//validates minimum length, nullity and special characters
Validator.AsPersonName(name);
#endregion
Id = new Guid();
Name = name;
PrimaryPhone = primaryPhoneNr;
}
}
我的问题是:假设这将被转换并提供给 MVC 视图,并且用户想要更新 AlternatePhone、电子邮件和许多其他属性,这些属性对于给定的有界上下文存在于该实体中是有意义的(为简洁起见未显示)
我知道正确的指导是为每个操作制定一个方法,但是(我知道它有点反模式)我忍不住想知道这是否最终会触发对数据库的多次更新调用。
这是如何处理的?在线的某个地方,是否会有将我的 EventOrganizer 映射到某个东西的东西 - 比如 DbEventOrganizer 并收集对域实体所做的所有更改并一次性应用这些更改?
你问的太笼统了!
EventOrganizer 本身不应更新任何内容。您应该将更新代码与实体完全分开。不同的 class 将采用 EventOrganizer 对象并更新数据库。这称为 'persistence ignorance' 并使代码更加模块化和内聚。
创建视图模型很常见 - class 其目的是以视图所需的确切形式为视图提供所需的确切数据。您需要从 EventOrganizer 创建视图模型,之后视图可以更新它 - 以编程方式或绑定方式。当您准备好保存更改时,您需要从视图模型更新您的 EventOrganizer 并将其传递给更新程序。当项目小而简单时,这似乎是一个你不需要的层,但随着复杂性的增加,它变得非常宝贵。
DDD 更适合基于任务的 UIs。您所描述的是非常面向 CRUD 的。在您的情况下,单个属性被视为独立的数据字段,其中一个或多个可以通过单个通用业务操作(更新)进行更新。
如果您想成功使用 DDD,则必须对您的域执行比这更深入的分析。
为什么有人会同时更新所有这些字段?用户试图通过这样做实现什么隐含的业务操作? PrimaryPhone
、AlternatePhone
、Email
一起变化,有没有更具体的业务流程?
也许这正在改变 EventOrganizer
的 ContactInformation
?如果是这种情况,那么您可以在 EventOrganizer
上模拟单个 ChangeContactInformation
操作。然后,您的 UI 将发送 ChangeContactInformation
命令而不是 update
命令。
至于聚合根 (AR) 的持久性,如果您使用 RDBMS,这通常由 NHibernate 等 ORM 处理。但是,还有其他方法可以持久化您的 AR,例如事件源、NoSQL 数据库甚至 storing JSON 或 RDBMS 中的任何其他数据交换格式。
所以,我决定学习 DDD,因为它似乎可以解决我一直面临的一些架构问题。虽然有很多视频和示例博客,但我还没有遇到指导我解决以下情况的视频和示例博客:
假设我有实体
public class EventOrganizer : IEntity
{
public Guid Id { get; }
public string Name { get; }
public PhoneNumber PrimaryPhone { get; }
public PhoneNumber AlternatePhone { get; private set; }
public Email Email { get; private set; }
public EventOrganizer(string name, PhoneNumber primaryPhoneNr)
{
#region validations
if (primaryPhoneNr == null) throw new ArgumentNullException(nameof(primaryPhoneNr));
//validates minimum length, nullity and special characters
Validator.AsPersonName(name);
#endregion
Id = new Guid();
Name = name;
PrimaryPhone = primaryPhoneNr;
}
}
我的问题是:假设这将被转换并提供给 MVC 视图,并且用户想要更新 AlternatePhone、电子邮件和许多其他属性,这些属性对于给定的有界上下文存在于该实体中是有意义的(为简洁起见未显示)
我知道正确的指导是为每个操作制定一个方法,但是(我知道它有点反模式)我忍不住想知道这是否最终会触发对数据库的多次更新调用。
这是如何处理的?在线的某个地方,是否会有将我的 EventOrganizer 映射到某个东西的东西 - 比如 DbEventOrganizer 并收集对域实体所做的所有更改并一次性应用这些更改?
你问的太笼统了!
EventOrganizer 本身不应更新任何内容。您应该将更新代码与实体完全分开。不同的 class 将采用 EventOrganizer 对象并更新数据库。这称为 'persistence ignorance' 并使代码更加模块化和内聚。
创建视图模型很常见 - class 其目的是以视图所需的确切形式为视图提供所需的确切数据。您需要从 EventOrganizer 创建视图模型,之后视图可以更新它 - 以编程方式或绑定方式。当您准备好保存更改时,您需要从视图模型更新您的 EventOrganizer 并将其传递给更新程序。当项目小而简单时,这似乎是一个你不需要的层,但随着复杂性的增加,它变得非常宝贵。
DDD 更适合基于任务的 UIs。您所描述的是非常面向 CRUD 的。在您的情况下,单个属性被视为独立的数据字段,其中一个或多个可以通过单个通用业务操作(更新)进行更新。
如果您想成功使用 DDD,则必须对您的域执行比这更深入的分析。
为什么有人会同时更新所有这些字段?用户试图通过这样做实现什么隐含的业务操作? PrimaryPhone
、AlternatePhone
、Email
一起变化,有没有更具体的业务流程?
也许这正在改变 EventOrganizer
的 ContactInformation
?如果是这种情况,那么您可以在 EventOrganizer
上模拟单个 ChangeContactInformation
操作。然后,您的 UI 将发送 ChangeContactInformation
命令而不是 update
命令。
至于聚合根 (AR) 的持久性,如果您使用 RDBMS,这通常由 NHibernate 等 ORM 处理。但是,还有其他方法可以持久化您的 AR,例如事件源、NoSQL 数据库甚至 storing JSON 或 RDBMS 中的任何其他数据交换格式。