【问题标题】:NHibernate - Domain Driven Design - Business Rule QuestionNHibernate - 领域驱动设计 - 业务规则问题
【发布时间】:2010-01-20 11:08:32
【问题描述】:

我有一个员工在一个集合中拥有多个地址。

public class Employee
{
    public string Name { get; set; }

    public AddressCollection Addresses { get; }
}


public class AddressCollection : IEnumerable<Address>
{
    private readonly Employee employee;
    private IList<Address> items = new List<Address>();

    public void AddAddress(Address address)
    {
        if (items.Contains(address)) return;

        address.Employee = employee;
        items.Add(address);
    }

    public void RemoveAddress(Address address)
    {
        items.Removce(address);
    }

    /// further IEnumerable implementations
}

public class Address
{
    public AddressType Type { get; set; }
    public City City { get; set; }
    public string Street { get; set; }

    public DateTime ValidFrom { get; set; }
    public DateTime ValidTo { get; set; }
}

public enum AddressType
{
    Default,
    ShippingAddress
}

一次只能有一个特定类型的地址有效。因此,当添加一个从 1-1-2009 到 15-1-2009 有效的默认类型地址,然后添加另一个从 10-1-2009 到 15-1-2009 有效的默认类型地址时,需要引发异常。

从 DDD 的角度来看,最好的方法是什么?当然,在 AddAddress 方法 中,我可以遍历现有地址并抛出异常。

但由于需要在表示层检查此业务规则以向用户显示消息,我不应该为此使用可在内部以及在表示层中使用的规范吗?

你会如何解决这个问题?

【问题讨论】:

    标签: .net nhibernate design-patterns domain-driven-design


    【解决方案1】:

    首先,我将摆脱您的 AddressCollection 类并在 Employee 上实现其成员。

    为了验证这样的规则,我推荐specification pattern。不需要像维基百科的文章那么复杂,可以很简单:

    public class CanAddAddressToEmployeeSpec
    {
        public bool IsSatisfiedBy(Address candidate)
        {  // logic to check address }
    }
    

    然后,您可以使用该类在添加之前检查是否可以将地址添加到员工,这样您的员工对象就不会进入无效状态。我还经常将 Messages 属性添加到规范中,如果 IsSatisifiedBy 为 false,则返回解释。

    如果您需要更多信心,可以为 EmployeeAddressesAreValidSpec 创建一个类似的规范,将 Employee 作为 IsSatisfiedBy 的候选参数,并在持久化数据之前对其进行检查。

    【讨论】:

      【解决方案2】:

      我建议使用 Microsoft 模式和实践团队发布的企业库中的 Validation Application Block

      这允许您将验证逻辑放在域对象上(维护 DDD),还可以填充对象,然后询问它是否有效,而不是抛出异常。

      我不确定您的 UI 是什么,但验证应用程序块可以与 ASP.NET、Windows 窗体和 WCF 集成。

      【讨论】:

        【解决方案3】:

        我同意里科的观点。开始查看验证应用程序块。 This article 可能会对您有所帮助,因为它描述了如何将 VAB 与 O/RM 框架集成。虽然本文重点介绍 LINQ to SQL 和实体框架,但我预计 NHibernate 不会有任何意外。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-03-16
          相关资源
          最近更新 更多