【问题标题】:Is this Domain-Driven Design?这是领域驱动设计吗?
【发布时间】:2012-06-08 02:45:52
【问题描述】:

致领域驱动开发专家...

我正在尝试真正掌握 DDD 的概念。到目前为止,我一直在将我的模型设计为数据驱动而不是域驱动。我已经阅读了几篇关于 DDD 的文章,看起来非常有趣,尤其是对于大型应用程序。所以我正在尝试定制我的模型来做到这一点。

我说过一个客户实体公开了一个 FreezeAccounts 方法,该方法将禁用所有客户帐户。此方法与数据访问无关(基于 Persistence Ignorance 规则)。它更新每个客户帐户上的标志(按需加载)并将更改保存到数据库。基于这个模型是正确的吗?我已经读过,在 DDD 中,每个表实体不一定只有一个类。这个功能应该在一个单独的类中吗?下面是一些示例代码:

public class Customer : ICustomer, ICustomerAction
{
    #region Initialization
    public Customer()
    {
    }

    internal Customer(ICustomer view)
    {
        this.CustomerId = view.CustomerId;
        this.Name = view.Name;
        this.Email = view.Email;
        this.IsActive = view.IsActive;
    }
    #endregion

    #region Instances

    private AccountCollection _accounts;

    #endregion

    #region Properties

    #region ICustomer

    public int CustomerId { get; private set; }
    public string Name { get; set; }
    public string Email { get; set; }

    #endregion

    #region Derived

    public AccountCollection Accounts
    {
        get
        {
            if (_accounts == null)
                _accounts = Account.GetListByCustomerId(CustomerId);
            return _accounts;
        }
    }

    #endregion

    #endregion

    #region Methods

    #region CRUD

    // Data Access Object accepts interface ICustomer
    internal void Update()
    {
        CustomerDb.Update(this); 
    }

    #endregion

    #region ICustomerAction

    // Exposed business Persistence Ignorance action
    internal void FreezeAccounts()
    {
        foreach (Account account in this.Accounts)
        {
            account.IsEnabled = false;
            account.Update();
        }
    }

    #endregion

    #endregion
}

【问题讨论】:

  • 现在一切都清楚了。我的例子是遵循传统的 Active Record 模式,而不是 DDD。业务对象与存储库交互,而不是让应用程序服务与存储库和域(服务/实体)交互。关键词:工作单元、实体根和服务帮助清晰了画面。谢谢!
  • 那你为什么不接受正确的答案呢? :-)

标签: architecture domain-driven-design


【解决方案1】:

首先,在DDD中和其他架构一样,数据访问层必须从领域和业务逻辑中分离出来,所以不能对实体进行CRUD操作.

所以要回答,是的,创建一个单独的层(不仅仅是一个类)来读取/写入存储上的数据,特别是在 DDD 中,您可以使用 Martin Fowler 的 RepositoryUnit Of Work 模式。

如果您想要 DDD 的示例,请查看 here

注意:我必须在 NuGet 上发布我的 DDD 架构“视图”的新版本。

【讨论】:

  • 感谢您指出这一点,完全同意单独的数据访问层。 CustomerDb.Update 已经是用于数据访问的不同类(DAL),在 ADO.NET/LINQ 中传递参数(使用接口轻松插入)因此 Customer 类(在 BLL 内部)仅调用其接受类型参数的方法“Update”客户。我为常用的层、MVC、会话外观、BLL 和 DAL 以及单元测试编写了自己的代码生成器。我真正关心的是理解以数据为中心和以领域为中心的架构之间的区别。有趣的文章,期待您的修改。
【解决方案2】:

使用 DDD,您希望清楚地了解什么是实体(具有唯一 ID,并作为一个单独的单元持续存在),什么是实体根(您希望向外界公开的实体),什么是服务(管理实体之间交互的代码)。

项目在数据库中的持久化方式可能与其实体对象完全不同 - 但由于您只处理实体,因此外部世界不必担心这一点,它被抽象到 DAL 中。

在您的示例中,您充分利用了对接口(SOLID 中的 I)的编程,这很好,但在不了解系统意图的情况下,很难说此示例是否遵循 DDD。

【讨论】:

    猜你喜欢
    • 2011-10-06
    • 1970-01-01
    • 1970-01-01
    • 2016-09-29
    • 1970-01-01
    • 1970-01-01
    • 2011-01-30
    • 2011-02-04
    相关资源
    最近更新 更多