Бизнес-объект, который обращается к хранилищу данных для проверки себя: нарушение SRP?

Рассмотрим следующий класс бизнес-объектов. Чтобы проверить себя, ему нужно что-то знать о состоянии базы данных, возможно, чтобы предотвратить какой-либо конфликт. Таким образом, он зависит от уровня доступа к данным для получения этих данных.

Является ли нарушением принципа единой ответственности наличие класса, который инкапсулирует состояние, проверяет состояние и обращается для этого к хранилищу данных?

class MyBusinessObject
{
    private readonly IDataStore DataStore;

    public MyBusinessObject(IDataStore dataStore)
    {
        this.DataStore = dataStore;
    }

    public virtual int? Id { get; protected set; }
    public virtual string Name { get; set; }
    // ... Other properties...

    public IEnumerable<ValidationResult> Validate()
    {
        var data = this.DataStore.GetDataThatInfluencesValidation();
        return this.ValidateUsing(data);
    }

    // ... ValidateUsing method would be in here somewhere ...
}

Для меня это красный флаг, потому что:

  • В контексте метода Create контроллера ASP.NET MVC я мог бы создать новый экземпляр и передать его моему методу View () без намерения проверки, так почему я должен передавать IDataStore?
  • Я использую NHibernate (и я новичок), и похоже, что мне нужно создать IInterceptor, который вводит зависимости всякий раз, когда NH создает объекты. Может быть, это будет хорошо, но мне это кажется немного неправильным.

Я начинаю думать, что должен использовать объект типа anemic / DTO для NHibernate и обернуть его во что-то еще, которое знает все бизнес-правила И может получить доступ к хранилищу данных, если это зависит от одного. Теперь, когда я ввел свой вопрос и название, StackOverflow предложил несколько интересных ресурсов: здесь и здесь.

Мой вопрос также очень похож на этот, но я думал, что спрошу иначе, что более точно соответствует моей ситуации.


person Andrew    schedule 11.01.2013    source источник


Ответы (1)


«Является ли нарушением принципа единой ответственности наличие класса, который инкапсулирует состояние, проверяет состояние и обращается для этого к хранилищу данных?» - Вы перечислили три обязанности, поэтому я отвечу утвердительно.

Сложность проверки состоит в том, что она зависит от контекста. Например, для создания записи о покупателе может потребоваться только его имя, но для продажи им продукта требуется информация о платеже и адрес доставки.

В MVC я выполняю проверку на низком уровне (размеры данных и допустимость значений NULL), используя аннотации данных в моделях представления. Более сложная проверка выполняется с использованием шаблона спецификации . Шаблон спецификации прост в реализации и гибок.

person Jamie Ide    schedule 12.01.2013
comment
Круто, я не слышал о шаблоне спецификации. Я также только что нашел FluentValidation сегодня через этот ответ. Кажется, что этот шаблон используется внутри, причем каждый класс в пространстве имен FluentValidation.Validators представляет спецификацию. Спасибо! - person Andrew; 15.01.2013
comment
Полагаю, мне также было интересно, можно ли сказать, что единственная ответственность класса состоит в реализации бизнес-задач, связанных с конкретным типом бизнес-объекта. С другой стороны, я не хочу заходить слишком далеко в SRP. Например, не так давно я написал проект, в котором было несколько классов, каждый из которых содержал только один метод. - person Andrew; 15.01.2013
comment
Мнения разнятся, но я считаю, что бизнес-класс обязан удерживать состояние и инкапсулировать доступ к состоянию (например, изменение статуса и изменение даты статуса должны происходить одновременно). - person Jamie Ide; 15.01.2013