NHibernate - Дизайн, управляемый доменом - Вопрос бизнес-правила - PullRequest
0 голосов
/ 20 января 2010

У меня есть сотрудник с несколькими адресами в коллекции.

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 я мог бы перебирать существующие адреса и выдавать исключение.

Но так как это бизнес-правило необходимо проверять на уровне представления, чтобы показать сообщение пользователю, не должен ли я использовать для этого спецификацию, которую я могу использовать как внутри, так и на уровне представления?

Как бы вы решили это?

Ответы [ 3 ]

5 голосов
/ 20 января 2010

Во-первых, я бы избавился от вашего класса AddressCollection и реализовал его члены в Employee.

Для проверки таких правил я рекомендую образец спецификации . Она не должна быть такой сложной, как статья в Википедии, она может быть просто:

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

Затем вы можете использовать этот класс, чтобы проверить, можно ли добавить Адрес к Сотруднику перед его добавлением, чтобы ваш объект Сотрудника не входил в недопустимое состояние. Я также часто добавляю свойство Messages в спецификацию, которая возвращает объяснение, если IsSatisifiedBy имеет значение false.

Если вам нужно больше уверенности, вы можете создать аналогичную спецификацию для EmployeeAddressesAreValidSpec, взяв Employee в качестве аргумента-кандидата для IsSatisfiedBy и проверить это перед сохранением данных.

0 голосов
/ 03 февраля 2010

Я согласен с Ричо. Начните смотреть на блок приложения проверки. Эта статья может помочь вам, так как в ней описывается, как интегрировать VAB со средами O / RM. Хотя статья посвящена LINQ to SQL и Entity Framework, я не ожидаю сюрпризов для NHibernate.

0 голосов
/ 20 января 2010

Я бы рекомендовал использовать Блок приложения проверки из Корпоративной библиотеки, выпущенный командой Microsoft Patterns and Practices.

Это позволяет вам поместить логику проверки в объект домена (поддерживая DDD), но также заполнить объект, и затем спросить , является ли он действительным, а не выдавать исключение.

Я не уверен, какой у вас интерфейс, но блок приложения проверки может быть интегрирован с ASP.NET, Windows Forms и WCF.

...