2011-07-07 170 views
1

再次 - 我感到困惑的事情DDD :)每個實體的一項服務?

我有architeture(我還在努力),在很短的手看起來像這樣:

DataLayer: 
EntityDao -> Implementing domain layer interfaces (NHibernate) 
DomainLayer: 
EntityRepository -> Repository for each entity with injected Dao 
DomainObjects/Entitys -> Some logic 
UI 
ASP.Net MVC 

而我現在正在那裏我覺得要創建和使用一些Service類。我有一些問題:

1.我應該爲每個實體/域對象創建至少一個服務嗎?

2.a.Should服務有「查詢」的方法,如查找,FIndAll,FindAll(LINQQuery)?

2.b.Should我應該停止使用上層(UI)中的Repositorys來獲取實體的集合(「查找」樣方法)並開始只使用服務?

3.如果對2個問題的回答是否 - 我應該以並行方式使用服務和存儲庫(在UI中時,我只需要獲取所有實體的使用Repository.FindAll,當我需要獲得一些「邏輯」列表該實體的我使用Service.FindXXX方法)?

4.我覺得Repositorys不適合在域層 - 我應該將它們分開嗎?在DOMAIN中只保留域特定的對象,如實體和服務?如果是 - 給我一些結構示例如何實現這一點。某些對象的

例子:

道:

public class NHibernateDao<T> : IDao<T> 
{ 
    public NHibernateDao() { } 

    public T Get(object id) 
    { 
     T entity = (T)NHibernateSession.Get(entityType, id); 
     return entity; 
    } 
    public T Load(object id) 
    { 
     T entity = (T)NHibernateSession.Load(entityType, id); 
     return entity; 
    } 
    public virtual T Update(T entity) 
    { 
     NHibernateSession.Update(entity); 
     return entity; 
    } 
    ... 

庫:

public class BaseRepository<T>:IRepository<T> 
{ 
    private DataInterfaces.IDao<T> mDao; 

    public virtual T Get(object id) 
    { 
     return mDao.Get(id); 
    } 
    public virtual void Delete(T entity) 
    { 
     mDao.Delete(entity); 
    } 
    public virtual T Update(T entity) 
    { 
     return mDao.Update(entity); 
    } 
    public virtual IQueryable<T> FindAll() 
    { 
     return mDao.FindAll(); 
    } 
    ... 

域對象,此刻,它的主要的get/set容器 - 這個問題的背景是去除貧血模型。

+0

你能舉一個EntityDao,EntityRepository和Entity的例子嗎? – Marijn

+0

啊,很明顯。如果這就是DAO和Repository的含義,那麼Kostassoid是對的,它們實際上是一樣的。 – Marijn

回答

6

1.每個實體一個服務?

不需要您爲一個實體創建一個服務。 在DDD中,您將爲不自然映射到單個實體(或值對象)的操作創建服務。一個很好的服務(從Evans):

  • 該操作涉及一個域概念,它不是一個實體或值對象的自然部分。
  • 該接口是根據域的元素定義的。
  • 操作是無狀態的

所以一個服務可以消耗大量的實體,有可能不是由單一的服務所消費的所有許多實體。

2a。服務應該具有「查詢」方法(..)嗎?

不是。一般來說,這些是存儲庫方法,不放在服務上。但是,可以對返回實體集合的服務進行操作。

2b.Should I stop to use Repositories in upper layers(UI)to set sets(「Find」-like methods)of entity's並且開始只使用服務?

這可能是一個好主意。通常,當應用程序在UI層中使用許多存儲庫時,UI會對多個實體執行域操作。這些操作通常應該在領域層實現;無論是在實體本身還是在服務中。

3.我應該在UI中並行使用服務和存儲庫嗎?

最好不要見上面;儘管可能會出現這種情況,您可以通過這樣做快速創建部分UI。

4.不知怎的,我覺得Repositoriess不適合領域層...

你說的沒錯,你應該只把庫接口域中。以Kostassoid的答案爲例。

5

我的想法(原諒我的英文):

  1. 服務提供業務邏輯上一級界面。一般來說,您應該隱藏自己的域級實現細節(較低),方法背後,基​​本上是命令或查詢。一種好的思考方式可能是在用例或用戶故事之後命名您的服務方法。而且您不應該提供更多的服務客戶端(UI)所需的功能。

2a。如果你的用戶界面需要某種類型的實體的所有數據,那麼是的,否則不。而FindAll()幾乎不是一個用例。

2b。您應該使用服務中的存儲庫,這實際上是您應該使用它的唯一地方。

3見2b。

4是的。您應該在您的域中留下存儲庫的接口,但實現應該在數據訪問中。然後你可以用一些IoC容器粘貼所有東西。可能是這樣的:

//in domain 
public interface IUserRepository { 
    User GetById(Guid id); 
} 
//in data access 
public class UserRepository : IUserRepository 
{ 
    public UserRepsitory(/* some orm specific dependencies */) { } 
    public User GetById(Guid id) { /* implementation */ } 
} 
+0

所以你說我應該刪除DAO的? – mgibas

+2

好吧,基本上Repository和DAO是解決相同問題的不同模式,所以我會說是的,我無法想象爲什麼你需要另一個抽象層。至少這是我的經驗告訴我的。 – Kostassoid

+0

關於2a:我在視圖助手和控制器中使用Repositories,在這種情況下,正確的將實現我的服務層中的查找方法?但這不會是責任的改變?我認爲在控制器或View Helpers中使用存儲庫只是爲了獲取數據是很好的,但不正確的做法是更改這些層中的數據。或者我錯了? – JCM

相關問題