DRY vs SoC

This time we look at design patterns and their correct interpretation.

mvvm00

A mistake

I don’t want to write a generic bla bla rant, so I’l focus on the following antipattern.

Someone wrongly suggests to change a property setter

public string PropertyA
{
    get { return propertyA; }
    set
    {
        myPropertyA = value;
        RaisePropertyChanged(nameof(PropertyA));  
        RaisePropertyChanged(nameof(IsPropertyAValid));
        ...
    }
}

to use the PropertyChange handler :

private void MyClass_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    switch(e.PropertyName)
    {
        case "PropertyA":
            RaisePropertyChanged(nameof(PropertyB));
            break;
    }
}

The claim would be to follow the DRY principle.

Correct approach

But that is not a violation of DRY. Let me rephrase it:

  1. each read-only property (let’s say PropX) has only a getter where you express it in terms of read-write properties
  2. for each read-write property (let’s say PropY) in the getter of PropX, you will raise property changed of PropX after raising the property changed of PropY in the setter of PropY
  3. after the above steps, whenever you find a duplicated list of calls for the same read-only properties, you can decide to collapse them into a single line method call (let’s say NotifyReadProps)

This is a simple and nice approach to manage two-way binding with MVVM. I’d suggest you follow it for common WPF UI. Otherwise you can choose a different pattern (not really a ViewModel) like Elm, React or F# Gjallarhorn are doing (but again, those are not typical C# style two-way binding)

Conclusions

Don’t break separation of concerns with event handlers.

The bad news is that a lot of devs believe that DRY is about avoiding repeating lines of code or properties names.

The concept is absolutely analogous: read VM instead of domain:

These handler classes do not belong in the domain model.

 

Advertisements

4 thoughts on “DRY vs SoC

  1. I concur with Giulio.

    Pertaining to C#, MVVM is an important and relevant architectural pattern, mainly in used with most things XAML (that includes WPF and Xamarin!).

    The main rationale behind MVVM (and similar architectural patterns, like for instance MVC and MVP), is Separation of Concerns (SoC) exactly, so, Giulio’s comment is right on the money!

    As a Design Principle, SoC is conceptually simple, and complementary to Single Responsibility Principle (SRP): responsibilities of a given kind or type should be segretated to its own layer (giving rise to an N-tier architecture), so, a given layer should only contain code that takes care of a single kind of responsibility.

    Getting back to MVVM and XAML, said code is basically Presentation Layer code, in particular, Views and ViewModels should only handle and include code that pertains (exclusively) to Presentation Layer responsibilities, with the Models being the nexus of the Presentation Layer with the other layers of the solution (through REST services, or Web Services, or the like). As the Models in MVVM are also running at the Presentation Layer (MVVM code in WPF and Xamarin is client code), these Models should be simple proxies of the actual Domain Objects, but not really Domain Objects (DOs), as they (the DOs) really belong to another layer, the Business Logic Layer.

    The Models in MVVM, as proxies of the DOs running in a Presentation Layer, they only are placeholders of the state of DOs that is needed at the Presentation Layer for the users to interact with said state of the DOs.

    So, MVVM code should only contain and handle Presentation Layer responsibilities. This is exactly what Giulio is pointing out.

    Kind regards, GEN

    Liked by 1 person

    • Thank you for your kind comments! Your ideas are always very welcomed.
      Here I wanted also to make a distinction between the ViewModel class and its base class.
      The latter has the responsibility to implement the `INotifyPropertyChanged`.
      As you explained in one of your blog posts, interface means abstraction in OOP.
      Long story short… that’s why I’m advising against subscribing the same event at the derived, specific VieModel class:
      it violates the single responsibility principle, only the VM base class is supposed to do that.

      Liked by 1 person

  2. Just as you have stated so well, MVVM in itself applies the concept of Separation of Concerns within the Presentation Layer … the implementarion of INotifyPropertyChanged is the sole responsibility of VM classes: The VMs care for a few relevant things: a) decoupling Views from Models (it is a VM that knows what models work with what views), and b) care about how the user interacts with the UI, and a “backstage” responsibility, c) data binding and bubbling of changes (bubbling event notifications to proper event handlers through the Chain of Responsibilities) … it is within the third group that lies what you are talking about.

    Kind regards, GEN

    Liked by 1 person

    • Excellent! Thank you again!
      So now we can imagine to divide the VM scope into 3 responsibilities – as you perfectly explained – or N responsibilities: then in OOP we can subclass them (in FP we would describe everything in terms of monads, functors, applicatives) and finally we have to keep them separate = loosely coupled – without mixing those handlers here and there and without making a “mess” – that was my point indeed, you’re correct.
      Glad you liked the article and very happy to read your great contribution here 😉

      Like

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 )

Google+ photo

You are commenting using your Google+ 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 )

Connecting to %s