2013-01-06 122 views
1

我正在设计一个新的大型应用程序,它需要尽可能灵活。
我选择了主要使用DDD的设计。
我的问题是关于将DTO对象返回到服务层的DO对象。设计DTO和DO服务层

即: 这是映射到数据库(使用ORM)我的域对象

public class Cat 
{ 
    int ID {get; set;} 
    string Name {get; set;} 
    string BloodType {get; set;} 
    string Color {get; set;} 

    void Run(){...} 
    void Purr() {...} 
} 

方法,并且只需要服务器操作的一些属性。
这就是为什么我设计了这个猫另一种类型,数据传输对象:

​​

在中间,我将建立一个对象映射到翻译我的DO对DTO的(反之亦然)。
当客户想更新猫的名字,他会叫这样

public void UpdateCat(CatDTO cat) 
{ 
    // What will happen here? 
    Cat serverCat = Mapper.GetCat(CatDTO); 

    CatDao.SaveOrUpdate(serverCat); 
} 

服务时映射器在翻译DTO对象回做,它会击中DB,以填补缺失Cat对象的属性(血型等) 针说这个动作是荒谬的,但没有填充空的属性,服务器端的其余部分无法使用Cat对象,因为它依赖于那些缺少的属性(即使我只是尝试更新数据库中的数据,我的ORM将更新bloodtype字段作为一个空字符串!)
我搜索了这个问题,并找不到在网络上的任何explenation(或至少有人谁是困扰这个问题,因为我)
我的设计方式错了吗?也许我错过了我的DDD的东西?
谢谢,帕维尔。

回答

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映射器。

+0

eulerfx,谢谢你的回应! 每次请求来自客户端时,点击数据库似乎仍然有点奇怪..也许我应该只是创建一个像UpdateCatName(id,name)这样的方法?或者最好的做法是坚持DTO的? –

+1

应用程序服务上类似'UpdateCatName(id,name)'的方法甚至更好,因为它不需要新类。如果您的架构需要,DTO可能仍然支持传输。 – eulerfx

+0

@PavelTarno我一直在做同样的事情。你有没有考虑过域层的汇编模式?如果您正在使用DTO,您正在使用什么进行消息传递?我拿它WCF?至于汇编模式,我在http://www.cs.sjsu找到了很棒的教程。edu /〜pearce/modules/patterns/enterprise/persistence/dto.htm(Java,但逻辑相同)和Microsoft站点http://msdn.microsoft.com/en-us/library/ms978717.aspx –