Domain driven design 我是否正确地设计和构建我的价值对象?
如果这个问题不清楚,请提前道歉。请告诉我如何改变,使之成为一个更好的问题 我目前正在维护一个C WinForm系统,我正在尝试学习和使用DDD和CQRS原理。Vaughn Vernon的实现领域驱动设计是我的主要DDD参考文献。 该系统目前使用传统代码,该代码使用数据感知控件。 在资产库存上下文中,我设计了我的聚合根资产,它由多个ValueObject组成,这些ValueObject是系统中的标准条目: 在此上下文中,我尝试实现一个用例,用户可以手动向系统注册资产 我目前的执行情况如下: 从表示层: 加载RegisterAssetForm.cs后,它通过数据感知控件加载组、项名称等的现有标准条目列表,所有这些控件都由columnsid:int和name:string的数据行组成。 当用户选择所需的ItemName、Group、PropertyLevel、Department和Category,然后单击save时,将执行一个命令: RegisterAssetForm.cs 从应用层: AssetInventoryApplicationService依赖于域服务。 AssetInventoryApplicationService.cs 从域层: AssetFactory.cs//不是我的最终实现 填充我的值对象的示例表 我知道域模型必须是持久性无关的,这就是为什么我打算在层超类型中使用带有valueobject的代理标识id字段来将持久性问题从域中分离出来 区分我的值对象的主要属性是它们的名称 从表示层,我通过命令将标准条目值作为与主键对应的整数id发送到使用域服务的应用层 问题 *创建命令时,我应该传递标准条目的id吗?还是应该传递字符串名称? *如果传递了id,如果需要名称,如何构造标准条目值对象? *如果传递了name,我是否需要从存储库中找出id? *还是我只是错误地设计了我的标准输入值对象?Domain driven design 我是否正确地设计和构建我的价值对象?,domain-driven-design,cqrs,value-objects,Domain Driven Design,Cqrs,Value Objects,如果这个问题不清楚,请提前道歉。请告诉我如何改变,使之成为一个更好的问题 我目前正在维护一个C WinForm系统,我正在尝试学习和使用DDD和CQRS原理。Vaughn Vernon的实现领域驱动设计是我的主要DDD参考文献。 该系统目前使用传统代码,该代码使用数据感知控件。 在资产库存上下文中,我设计了我的聚合根资产,它由多个ValueObject组成,这些ValueObject是系统中的标准条目: 在此上下文中,我尝试实现一个用例,用户可以手动向系统注册资产 我目前的执行情况如下: 从表示
谢谢您的帮助。在我看来,您可能混淆了值对象和实体 本质上的区别在于实体需要一个Id,而VO是一个东西,而不是一个特定的东西。CRM中的电话号码可能是VO。但如果你是一家电话公司,它很可能是中国的一个实体 我在这篇文章中有一个VO的例子,你可能会发现它很有用- 更具体地回答您的“问题”: 如果您正在创建某个实体,那么将id传递给命令可能是有利的。这样,您就已经知道id是什么了。 您不应该能够创建无效的值对象。 你为什么不能把名字和身份证传进来?再次-不确定这是否与值对象相关 我认为你设计得不对。但我不能确定,因为我不知道你的具体领域。
希望这有帮助 实际上,我的主要领域是资产实体。“值对象”组等描述了我的资产实体,并且在构建它时是必需的。是的,值对象有一个id,但这并不意味着它就是它的标识。虽然我的数据模型确实需要这些id,但这就是为什么我想到使用DDD书中描述的层超类型。1.我正在创建一个值对象,而不是一个实体,但我理解你的观点。2 & 4. 这非常有帮助,我可能需要重新设计我的模型。3.在命令中传递/包含的参数方面是否有最佳做法?可能重复
...
AssetInventoryApplicationService _assetInventoryServ;
...
void btnSave_Click(object sender, EventArgs e)
{
int itemNameId = srcItemName.Value // srcItemName is a custom control whose Value = datarow["id"]
int groupId = srcGroup.Value;
string categoryId = srcCategory.Value;
string departmentId = srcDepartment.Value;
string propLvlId = srcPropLevel.Value;
...
RegisterAssetCommand cmd = new RegisterAssetCommand(itemNameId, groupId, categoryId, departmentId, propLvlId);
_assetInventoryServ.RegisterAsset(cmd);
...
}
...
IAssetRepository _assetRepo;
...
public void RegisterAsset(RegisterAssetCommand cmd)
{
...
AssetFactory factory = new AssetFactory();
AssetID newId = _assetRepo.NextId();
Asset asset = factory.CreateAsset(newId, cmd.ItemNameId, cmd.PropertyLevelId,
cmd.GroupId, cmd.CategoryId, cmd.DepartmentId);
_assetRepo.Save(asset);
...
}
...
public class AssetFactory
{
...
public Asset CreateAsset(AssetID id, int itemNameId, int propLvlId, int groupId, int categoryId, int departmentId)
{
ItemName itemName = new ItemName(itemNameId);
PropertyLevel propLvl = new PropertyLevel(propLvlNameId);
Group group = new Group(groupNameId);
Category category = new Category(categoryNameId);
Department department = new Department(departmentNameId);
return new Asset(id, itemName, propLvl, group, category, deparment);
}
...
}
+------------+--------------+
| CategoryID | CategoryName |
+------------+--------------+
| 1 | Category1 |
| 2 | Category2 |
| 3 | Category3 |
| 4 | Category4 |
| 5 | Category5 |
+------------+--------------+