В каком слое должны быть объекты "Шаблон спецификации" "новыми"? - PullRequest
7 голосов
/ 23 ноября 2011

Итак, я посмотрел несколько постов о шаблоне спецификации здесь и не нашел ответа на этот вопрос.

Мой вопрос в n-слоистой архитектуре, где именно следуетменя Технические характеристики "обновлены"?

  1. Я мог бы поместить их в свой сервисный уровень (иначе, прикладной уровень, его иногда называют ... в основном, что-то, с чем будет обращаться код .aspx), но мне кажетсяделая это, я позволяю бизнес-правилам выходить за пределы домена.Если доступ к объектам Domain осуществляется другим способом (помимо уровня обслуживания), объекты Domain не могут применять свои собственные бизнес-правила.

  2. Я мог бы внедрить Спецификацию в свой класс Model с помощью внедрения конструктора,Но опять же, это чувствует себя "неправильно".Я чувствую, что единственное, что должно быть внедрено в классы Model - это «сервисы», такие как Caching, Logging, отслеживание грязных флагов и т. Д.классы с тоннами сервисных интерфейсов.

  3. Я мог бы внедрить Спецификацию посредством внедрения метода (иногда называемого «Двойной отправкой» ???), и явно иметь этот метод для инкапсуляции введенной Спецификациидля обеспечения соблюдения своего бизнес-правила.

  4. Создайте класс «Службы домена», который будет принимать спецификацию (-и) через внедрение конструктора, а затем позволит сервисному уровню использовать службу домена для координацииДоменный объект.Мне кажется, это нормально, так как правило, предписанное Спецификацией, все еще находится в «Домене», и класс службы домена можно назвать очень похожим на объект домена, который он координирует.Дело в том, что я чувствую, что пишу МНОГО классов и кода, просто для «правильной» реализации шаблона Спецификации.

Добавьте к этому, что рассматриваемая Спецификация требуетрепозиторий, чтобы определить, «удовлетворен» он или нет.

Это может привести к проблемам с производительностью, особенноесли я использую инъекцию в конструктор, b / c потребляющий код может вызвать свойство, которое, возможно, оборачивает спецификацию, и которое, в свою очередь, вызывает базу данных.

Так что, есть идеи / мысли / ссылки на статьи?

Где лучше всего искать и использовать технические характеристики?

Ответы [ 2 ]

7 голосов
/ 23 ноября 2011

Краткий ответ:

Вы используете спецификации в основном на своем уровне обслуживания, поэтому там.

Длинный ответ: Прежде всего, естьздесь два вопроса:

Где должны находиться ваши спецификации и где они должны быть новыми?

Как и ваши интерфейсы репозитория, ваши спецификации должны жить на уровне домена, как они есть.В конце концов, для конкретного домена.Есть вопрос по SO , в котором обсуждается это на интерфейсах репозитория.

Хотя, где они должны быть новыми?Ну, я использую LinqSpecs в своих репозиториях, и в большинстве случаев в моем репозитории есть три метода:

public interface ILinqSpecsRepository<T>
{
    IEnumerable<T> FindAll(Specification<T> specification);
    IEnumerable<T> FindAll<TRelated>(Specification<T> specification, Expression<Func<T, TRelated>> fetchExpression);
    T FindOne(Specification<T> specification);
}

Остальные мои запросы построены на моем сервисном уровне.Это предотвращает раздувание репозиториев с помощью таких методов, как GetUserByEmail, GetUserById, GetUserByStatus и т. Д. В моем сервисе я обновляю свои спецификации и передаю их методам FindAll или FindOne моего репозитория.Например:

public User GetUserByEmail(string email)
{
    var withEmail = new UserByEmail(email); // the specification
    return userRepository.FindOne(withEmail);
}

и вот спецификация:

public class UserByEmail : Specification<User>
{
    private readonly string email;

    public UserByEmail(string email)
    {
        this.email = email;
    }

    #region Overrides of Specification<User>

    public override Expression<Func<User, bool>> IsSatisfiedBy()
    {
        return x => x.Email == email;
    }

    #endregion
}

Итак, чтобы ответить на ваш вопрос, спецификации появились в слое обслуживания (в моей книге).

Мне кажется, что единственное, что должно быть введено в классы модели, это "сервисы"

IMO, вы не должны вводить что-либо в сущности домена.

Добавьте к этому, что для данной Спецификации требуется репозиторий, чтобы определить, «удовлетворен» он или нет.

Это запах кода .Я бы пересмотрел ваш код там.Спецификация определенно не должна требовать хранилища.

6 голосов
/ 23 ноября 2011

Спецификация - это проверка реализации бизнес-правила. Он должен существовать в полной остановке уровня домена.

Трудно дать конкретную информацию о том, как вы это делаете, поскольку каждая кодовая база отличается, но, по моему мнению, любая бизнес-логика должна быть на уровне предметной области, и больше нигде. Эта бизнес-логика должна быть полностью тестируемой и слабо связанной с пользовательским интерфейсом, базой данных, внешними сервисами и другими не доменными зависимостями. Так что я бы определенно исключил 1, 2 и 3 выше.

4 - вариант, по крайней мере, спецификация будет жить на уровне вашего домена. Однако обновление спецификаций снова зависит от реализации. Мы обычно используем внедрение зависимостей, поэтому обновление почти всех наших объектов выполняется через контейнер IOC и соответствующий код начальной загрузки (т.е. мы обычно проводим приложение свободно). Однако мы бы никогда не связали бизнес-логику напрямую, например, с UI модели классов и тому подобное. У нас обычно есть контуры / границы между такими вещами, как пользовательский интерфейс и домен. Обычно мы определяем контракты на обслуживание домена, которые затем могут использоваться внешними уровнями, такими как пользовательский интерфейс и т. Д.

Наконец, мой ответ состоит в том, что система, над которой вы работаете, по крайней мере, несколько сложна. Если это очень простая система, доменно-ориентированный дизайн как концепция, вероятно, слишком перегружен. Однако некоторые понятия, такие как тестируемость, читаемость, SoC и т. Д. Должны соблюдаться независимо от кодовой базы, на мой взгляд.

...