2013-04-08 115 views
3

我有一個名爲Person的聚合根。該人也有一個地址。這些類之間的關係是ManyToOne(許多人共享相同的地址)。DDD - 是否允許工廠訪問存儲庫?

這意味着,當我使用一個工廠創建一個新的人與一個特定的地址,我必須檢查是否有相同的地址在數據庫中已存在並使用exisiting地址的用戶。

這需要我廠有機會獲得一個地址庫(或直接到數據庫)。這是否允許?如果不是,那麼做一個更好的方法是什麼?

//編輯 我的解決辦法是現在以下幾點:

我有一個類PersonService持有登記一個人的邏輯。方法register()已經佔用由AddressFactory創建的地址對象。 Addressfactory可以訪問AddressRepository來檢查輸入的地址是否已經存在。下面的代碼:

public class PersonService{ 

    @Inject private PersonRepository pRepo; 

    public Person register(Name name,..., Address address){ 
     //check if same person exists, 
     //create person, persist person 
     return person; 
    } 
} 

public class AddressFactory{ 
    @Inject AddressRepository aRepo; 

    public Address create(String street, int number, ...){ 
     //check if address with attribues exists in repo, 
     //if not create new address 
     return address; 
    } 
} 

和一些豆類調用此方法是這樣的:

personService.register(new Name("test"),..., addressFactory.create("Some street", 1,...)) 

你覺得呢?

+0

只是澄清 - 你說的是從用戶輸入的內容中推導出一個現有的地址,對嗎?你會問用戶他是要選擇那個地址還是默默地將它與指定的地址等同起來?這個想法默默地等同於 – guillaume31 2013-04-08 15:00:17

+0

。 – user1727072 2013-04-09 07:02:38

回答

3

這意味着,當我使用一個工廠創建一個新的人與一個特定的地址 ,我不得不檢查,如果同一地址 已經存在的數據庫,並使用exisiting地址用戶。

如果你按照單一責任原則來處理這封信,你不應該那樣做。 PersonFactory不應該創建Addresses而是Persons

甚至更​​少,所以當Address創建包括複雜的邏輯,如檢索在類似於或多或少是由用戶填寫(如果那是你真正想要什麼)地址數據庫中的Address。你應該把它委託給另一個對象。

+1

在這種情況下,[SRP](http://epic.tesio.it/doc/manual/solid_principles.html#about_single_responsibility)要求PersonFactory僅在創建Person實例的邏輯發生更改時纔會更改。這並不意味着它只應該執行一個**新的**。此外,它**將**地址訪問委託給另一個對象:地址的存儲庫。 – 2013-04-08 13:29:18

+3

它確實委託地址訪問,但不是有條件地創建地址(如果不存在)的邏輯。對我來說,這是另一個改變的理由,還有一個責任。 – guillaume31 2013-04-08 14:52:05

+1

+1很對。 – 2013-04-08 15:06:32

1

是的,只要工廠使用的人的倉庫(而不是由人本身),這是一個有效的解決方案。

但是你應該考慮,如果在你的領域模型中,人真正需要他們的地址,以保證業務不變量。如果沒有,請刪除該人的地址,並使用專門爲這種投影範圍定義的PersonDTO

+0

我剛剛注意到你寫了「..工廠被人使用的倉庫」。但我的問題是另一種方式:工廠可以使用存儲庫來測試數據庫中是否存儲了相同的對象? – user1727072 2013-04-08 11:52:57

+0

@ user1727072您詢問人員回購中的工廠是否可以使用地址回購。這很好。 – 2013-04-08 11:57:07