每个实体一项服务?

mgi*_*bas 1 architecture design-patterns domain-driven-design

再次 - 我对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
Run Code Online (Sandbox Code Playgroud)

我现在正处于创建和使用某些Service类的那一点.我有一些问题:

1.我应该为每个实体/域对象创建至少一个服务吗?

2.a.Should服务有"查询"方法,如Find,FIndAll,FindAll(LINQQuery)?

2.b.我应该停止在上层(UI)中使用Repositorys来获取实体的集合("类似于查找"的方法)并开始只使用服务吗?

3.如果回答2问题是否 - 我应该以并行方式使用服务和存储库(在UI中我只需要获取所有实体我使用Repository.FindAll,当我需要获得该实体的一些"逻辑"列表时使用Service.FindXXX方法)?

4.我在某种程度上认为Repositorys不适合Domain层 - 我应该以某种方式将它们分开并在DOMAIN中只留下像Entity和Services这样的域特定对象吗?如果是 - 给我一些结构示例如何实现.

一些对象的例子:

道:

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;
    }
    ...
Run Code Online (Sandbox Code Playgroud)

库:

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();
    }
    ...
Run Code Online (Sandbox Code Playgroud)

域对象,目前,它主要是获取/设置容器 - 这个问题的背景是去除那个贫血模型.

Mar*_*ijn 8

1.每个实体一项服务?

不需要.您不需要为一个实体创建一个服务.在DDD中,您将为不自然映射到单个实体(或值对象)的操作创建服务.优质的服务(来自埃文斯):

  • 该操作涉及域概念,该概念不是实体或值对象的自然部分.
  • 接口是根据域的元素定义的.
  • 这项行动是无国籍的

因此,服务可以消耗许多实体,并且可能有许多实体根本不被单个服务消耗.

2A.服务应该有"查询"方法(..)吗?

一般来说,这些是存储库方法,不会放在服务上.但是,可以对返回实体集合的服务进行操作.

.我应该停止在上层(UI)中使用存储库来获取实体的集合("类似于查找"的方法)并开始只使用服务吗?

这可能是一个好主意.通常,当应用程序在UI层中使用许多存储库时,UI会对多个实体执行域操作.这些操作通常应该在域层中实现; 无论是在实体本身,还是在服务中.

3.我应该从UI并行使用服务和存储库吗?

最好不要,见上文; 尽管可能存在这样的情况:您可以通过这种方式快速创建UI的一部分.

不知怎的,我觉得Repositoriess不适合Domain层......

你是对的,你应该只在域中放置存储库接口.以Kostassoid的答案为例.


Kos*_*oid 6

我的想法:

  1. 服务为业务逻辑提供上层接口.通常,您应该隐藏它的方法背后的域级实现细节(较低),基本上是命令或查询.一种好的思维方式是在用例或用户故事之后命名您的服务方法.并且您不应该提供服务客户端(UI)所需的更多功能.

2A.如果您的UI需要来自某种类型实体的所有数据,则为是,否则为否.而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 */ }
}
Run Code Online (Sandbox Code Playgroud)

  • 好吧,基本上Repository和DAO是解决同一问题的不同模式,所以我会说是的,我无法想象为什么你需要另一个抽象层.至少这是我的经验告诉我的. (2认同)