2016-09-30 60 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

相關問題