2016-09-30 61 views
1

同事正在使用“实体和Dtos”的惯例在我们的应用程序中实现存储库模式。这是他的想法,我不熟悉这些成语。我应该在储存库界面外创建储存库项目吗?

目前,实体和DTO的之间的主要区别是:

  • 实体有一个ID字段(DTOS有太多,我觉得很臭);
  • Dtos有Clone方法;
  • 实体属性具有更好的序列化友好数据类型,转换由data-mappers执行;

的问题是:

我应该在客户端自由地创建我的DTO,并然后它们发送到回购?或者我应该要求新的Dto实例只有在回购界面?

这将是之间的区别:

TDto dto = new TDto(); 
// edit dto properties 
repo.Add(dto) 

TDto dto = repo.Add(); // repo : Repository<TDto> 
// edit dto properties 
repo.Update(dto); 

有没有preferrable方式?如果这是一个偏好问题,我更喜欢第二种选择,我应该注意不要让自己陷入某个角落? (免责声明:坦率地说,我认为这个Entity/Dto对于我们这个相对简单的客户端桌面应用来说太过分了,它只有基于序列化的CRUD需求,但是我愿意遵循“模式”,只要它解决了问题,而不是凑了过来)

UPDATE:

的一个问题,我目前面临的,并试图解决的是“臭id属性”。目前,添加时在Id中设置了Id。该代码是这样的:

public Patient Add(Patient patient) 
    { 
     patient.Id = Guid.NewGuid(); 
     var entity = patient.ToEntity(); 
     _patientsCache.Add(entity); 
     this.Salvar(); 
     return patient; 
    } 

注意,这个方法调用返回相同的DTO,只是现在它的ID设置为通过回购创造价值。我的头脑看着这个,并认为“这是不对的”,但我无法令人信服地证明这一点。

+1

调用'Add()'并不期望它实际添加任何内容到底层存储。也许'new()'或'create()',但是仓库不应该负责创建你的类的实例,IMO。 –

+0

@ stephen.vakil感谢您的关注。我已经更新了实际代码的剪切问题。身份证字段 - 谁创造它,什么时候 - 是最让我困扰的。 – heltonbiker

+0

好的,如果我正在做出正确的假设,那么您更新的模式对我来说是完全合理的。如果你想隐藏存储库之外的实体框架的存在,那么让repo层采用映射到实体的dto是合理的。当你正在做一个添加时,如果它是由数据库生成的,你通常会希望这个ID回来,因为你可能想对'patient'采取进一步的行动。 –

回答

1

最终,复杂性和架构决策没有“正确”的答案。正如您所指出的那样,如果应用程序很小,将太多图层设计到其中可能会过度。另一方面,如果应用程序规模增大,以后很难重构。

至于在哪里实例化DTO的问题;它只是实例化。如果你调用默认构造函数,并且你的构造函数以非臭方式工作 - 即它不执行复杂的逻辑或者做有副作用的事情,而只是设置你的默认或“空”实例DTO - 那么它确实无关紧要。

我会说在客户端做它,因为它更简单,并节省您一次往返。

如果您不希望客户知道DTO中的“ID”字段,请将其设置为internal字段或属性,并将其设置为存储库代码。

+0

不错!但有一个问题:由于Dtos有一个ID字段,因此回购可以知道要更新哪个实体实例,您认为何时以及何时创建该Id是明智的?目前,Dto的构造函数没有设置Id - 这是通过'repo.Add(TDto dto)'方法设置的。但TDto然后有一个公共身份证财产!你有什么建议吗? – heltonbiker

+0

坚持,我正在检查[福勒](http://www.martinfowler.com/books/eaa.html)(顺便说一句,好书)。 –

+0

我用实际的代码更新了我的问题,顺便说一下,在我的例子中是两个签名的组合。我发现它非常臭,但不知道它是什么味道... – heltonbiker

相关问题