Single Responsibility Misuse

The Inquisitive Coder recently made a post about MVVM being overrated. He states a preference for MVP (a great pattern, and a great implementation of it for WPF is Caliburn). Whilst patterns are there to be abused used as the needs of a project dictate. I think the arguments are subject to a common flaw in peoples thinking, especially around front-end patterns.

The primary attack on MVVM is that it violates the Single Responsibility Pattern (SRP). In short SRP states that a class should have one and only one reason to change. David suggests that ViewModels have 2 reasons to change (paraphrased)

  1. If, the Model changes
  2. If, the View requirements change ( i.e. needs more model data displayed/edited)

This is not what I take issue with, it’s true. But it’s true of all bridge classes and interfaces; DTO’s, Data Layers and UI’s. A bridge depends on both sides, but that is it’s responsibility. Sometimes the SRP is looked at from a much to granular view point and it leads to anaemic domains. People want to separate data from behaviour it seems to be human nature. I regularly hear SRP as the reason why this is good.

From Daniels post the 2 responsibilities a ViewModel has are:

  • communication/interaction with the Model
  • making data (from the Model) available so it can be displayed

Rephrased

  • Behaviour
  • Data

The SOLID principles (of which the S stands for SRP) are a great way to evaluate code and patterns, but they take a back seat to the tenets of OO Design

  • encapsulation
  • inheritance (I think this should be renamed Inheritance and Composition or removed as being implicit in polymorphism)
  •  polymorphism

Encapsulation states thou shall not whore out your data to other classes. Whilst UI is a grey area for encapsulation as we all need to display our data. MVVM takes a step closer to encapsulation by keeping the behaviour and data together.

In my opinion ViewModels contain their data and the behaviour that relies on it in one place with the single responsibility of Modelling a View.  If your ViewModels are two big or unwieldy then look at decomposing them into self contained Commands (with both data and behaviour) and/or smaller ViewModels with clearer responsibilities (an upcoming post).

Side Note
After 18 months of MVVM I too am starting to wonder if the extra work required to maintain two-way synchronization (View-Model) is worth it for most scenarios. But that’s another topic and to do with choosing the right tool for the job. I still believe MVVM is the most elegant pattern for solving the problem it solves.

Advertisements

2 thoughts on “Single Responsibility Misuse

  1. Davy Brion says:

    i think you misunderstood a few things about my post

    i don’t advocate a seperation of data and behavior, nor did i even mention that

    what you categorize as Data (the ‘making data (from the Model) available so it can be displayed’) is something i’d categorize as both Data _and_ Behavior

    The Data part being the properties, the Behavior part being the notification events that need to be triggered _at the right time_ and _in the right situations_ (which becomes important if you’re binding to properties that are dependent on data of other properties)

    The ViewModel contains the data, behavior that is relevant to that data, and it _also_ interacts with the model to retrieve/update that data and to execute business logic

    at which point is it enough to say “ok you know what, we’re starting to do too many things in the same place here…”?

  2. adammills says:

    MVP inheritantly suggests the seperation of Data and behaviour into two distinct components the model and the presenter.

    I definately try to seperate out as much of the noise as possible when it comes to the “data behaviour” so it is just data.
    PropertyChange and Dependency is handled through interception. So ViewModel Properties are as such

    [NotifyOnChange]
    public virtual string Name
    {
    get { return model.Name; }
    set { model.Name = value; }
    }

    [DependsOn(“Name”)]
    public virtual string CalculatedField
    {
    get { return CalculationWithName(); }
    }

    interaction with repositories and the delegating busniess logic to the model is done in async commands.

    When i feel there is too much going on I look for behaviour and data that can be moved into a new command or viewmodel. For me better decomposition and seperating out orthogonal concerns are an important part of worknig with this still developing pattern.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: