我正在设计一个新的大型应用程序,该应用程序需要尽可能灵活
我选择主要用DDD设计..
我的问题是关于将DTO对象转移回服务层中的DO对象。
即: 这是我的域对象映射到DB(使用ORM)
public class Cat
{
int ID {get; set;}
string Name {get; set;}
string BloodType {get; set;}
string Color {get; set;}
void Run(){...}
void Purr() {...}
}
只有服务器操作才需要方法和一些属性 这就是我为这种猫类设计另一个数据传输对象的原因:
public class CatDTO
{
int ID {get; set;}
string Name {get; set;}
}
在中间,我会设置一个对象映射器,将我的DO转换为DTO(反之亦然)。
当客户想要更新猫的名字时,他会拨打这样的服务
public void UpdateCat(CatDTO cat)
{
// What will happen here?
Cat serverCat = Mapper.GetCat(CatDTO);
CatDao.SaveOrUpdate(serverCat);
}
当映射器将DTO对象转换回DO时,它必须命中DB以填充Cat对象的缺失属性(血型等等)#9;)
有人说这个动作是荒谬的但是没有填充空属性,服务器端的其余部分无法使用Cat对象,因为它依赖于那些缺少的属性(即使我只是尝试更新数据库中的数据,我的ORM将更新血型字段为空字符串!)
我搜索了这个问题,并且无法在网上找到任何问题(至少有人像我一样对这个问题感到困扰)
我是以错误的方式设计的吗?也许我错过了DDD的东西?
谢谢,帕维尔。
答案 0 :(得分:4)
此用例的常用工作流程是:按ID检索映射的域对象,应用DTO指定的更新,提交工作单元。您所称的DAO通常称为DDD中的存储库。代码看起来应该更像:
public void UpdateCat(CatDTO catDto)
{
Cat cat = this.catRepository.Get(cat.ID);
cat.Name = catDto.Name;
this.catRepository.Commit();
}
Commit
步骤可以有多种方式。它可以是显式保存,也可以在UpdateCat
方法之外提交工作单元。此工作流程也适用于所有相关方案。通常,域行为涉及检索适当的实体,在该实体上调用某些行为,然后将得到的更改提交给数据库。
此外,DTO不应直接映射回现有实体。相反,最好将它们视为表示要应用于现有实体的更改,并且代码应该反映这一点。这部分是因为存储库“拥有”现有实体,而存储库负责重构,而不是DTO映射器。