Consider the following business entity class. In order to validate itself, it needs to know something about the state of the database, perhaps to prevent a conflict of some kind. So, it has a dependency on the data access layer in order to retrieve this data.

Is it a violation of the Single Responsibility Principle to have a class that encapsulates state, validates the state, and accesses a data store to do so?

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 ...
}

It's throwing a red flag for me because:

  • In the context of an ASP.NET MVC controller's Create method, I might make a new instance and pass it to my View() method with no intention of validating, so why should I be required to pass in an IDataStore?
  • I'm using NHibernate (and I'm a noob), and it looks like I have to create an IInterceptor that injects dependencies whenever NH creates entities. Maybe that will be fine, but it feels a little bit wrong to me.

I'm starting to think I should use an anemic/DTO type of object for NHibernate to use, and wrap that inside something else that knows all the business rules AND can access a data store if it depends on one. Now that I've typed up my question and title, StackOverflow has suggested some interesting resources: here and here.

My question also looks very similar to this one, but I thought I'd ask it in a different way that more closely matches my situation.

有帮助吗?

解决方案

"Is it a violation of the Single Responsibility Principle to have a class that encapsulates state, validates the state, and accesses a data store to do so?" -- You listed three responsibilities so I'm going to answer yes.

The difficulty with validation is that it depends on context. For example, creating a customer record might require just their name but selling them a product requires payment information and a shipping address.

IN MVC, I do low level (data sizes and nullability) validation using data annotations in view models. More complex validation is done using the specification pattern. The specification pattern is easy to implement and flexible.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top