mwpowellhtx (4) [Avatar] Offline
#1
Hello,

I'm reading through Chapter 2 the bad and good example, and the good is definitely better than the bad. However, I am finding that there is a design flaw lurking about that is exposed, and which I've personally encountered, particularly in MVVM type frameworks such as WPF and the like.

In general, I've found that any approach when adhered to religiously for the sake of adherence tends in the direction of liability more than asset, subtracts rather than adds to (or worse) maintainability. Outcome is usually TECHNICAL DEBT that you end up having to pay off in HIGH BALANCE and/or INTEREST.

Specifically, that there tends to be a DUPLICATION OF CONCERNS between domain objects themselves and whatever view models are representing the domain objects throughout the code base.

The view model is one such culprit. Nine times out of ten I've found that letting the domain objects know how to operate themselves, as opposed to being simple POCOs, works out better. Domain concerns work themselves out from the inside out. Service, controller, and even view code should almost write itself without a great deal of extra effort.

When service and controller code is expected to operate the domain objects, the code starts to look like spaghetti, prone to all the pasta traps you might expect, repeating code (anything but DRY, possibly being WET), unmaintainable. Oh, there may be concerns that are loosely coupled, but the domain and view model are still unmaintainable in and of themselves. I tell folks: I like pasta in my diet, less so spaghetti in my code. Okay, no fault of DI per se.

With concrete like that tied around your ankles, it would be WET: I wouldn't go jumping off any piers and expect to swim for very long, if walk on water over a job well done. Unless there's a good reason, like you're wiring across machine or process boundaries, and even then I might challenge whether the same domain assemblies aren't involved on both sides of the wire, instead I find that letting the domain object report themselves from the inside out usually works out best.

The illustration I have is a recent WPF application I inherited, where my predecessor would religiously Accept and Create POCOs to/from ViewModels. Oh, and there are Views that involved parent-domain-object ObservableCollections from the OUTSIDE-IN. This was fine to a point, except when I needed a POCO to report itself to another view, so that I could update one of the other views: was failing the COMPOSITION test BIG TIME, pasta all over the place, very unwieldy.

I've found there will still be times when a specialized view needs to see only a portion of a domain object, but even then I would argue that perhaps two out of five, maybe three out of seven being generous, views ever need any sort of view model ADAPTING in a domain object: I'd challenge you to aim for 0.5 out of 5, if that.

Speaking to the book example, it's one thing you have a filter, like a Discounted Product in the example. Book illustration aside, I might argue whether that wasn't a more cross-cutting type concern, and see if it couldn't be Aspected across concerns: in other words, not taint the Product itself. Thinking in terms of: anticipating not whether but when the next cross cutting concern will need to addressed.

Best regards,

Michael Powell