Encapsulation is the enemy of the user interface

I got this question a while ago from Kyle, and I think is is a great one. It is especially great since it is an exchange of emails that resulted in the following (all of which are Kyle words):

I've been annoyed lately by the MVVM pattern. It seems like it requires that the data on your business classes be public so that the view-model can get at it, and that completely breaks encapsulation and goes against standard OO design theory (in my opinion).

The UI layer should be allowed to reference the data layer. I recalled a post you wrote where your UI needs to basically pull things out of queries and such directly (that's what I understood it to mean, anyway). I'm not sure how to pull this off easily just yet, because it seems like it would still break encapsulation somewhere down the line, but it's an interesting thought.

And yeah, I realized after sending the email about CQS. I've decided that my preferred way is actually having my model be able to create a view-model. It's still not pretty, but it's much better (in my view) than having all public data on my business models. I can use commands to bind directly to the model, and the view-model can cause that to happen correctly.

I thought about CQS more, and have a really nice way of doing the whole shebang, I think. It does kind of use your "Two different models for read vs write" concept. I've even come up with a little pseudo-enterprisey application to write using this design style. You'll like it - it's a Netflix for books [[netflix for books is a library]], essentially.

My answer to that is that Kyle is correct. On the one hand, we have the needs of the UI to show information, and on the other hand, we want to have good encapsulation for our business entities. UI forces us to expose information to the user, and that encourages properties laden models. The problem with this approach is that often we try to make use of the same model for several tasks, such as using business entities for user interface, or even asking the business entities to generate the view models that they represent.

CQS is a design methodology that is aimed at resolving this conflict, at its heart, it is actually very simple. It simply stipulate that you are going to have two different models for representing it. One for reads (queries) and another for writes (commands). Once we accept that, we can see that we can evolve each of those models independently. And then we get to the point where we see that the data storage mechanism that we use for each model can be optimize independently for each use case.

For example, when using commands, we generally perform lookups by primary key alone, so we can avoid the overhead of indexes, or even select a storage format that is suitable for key based lookups (DHT, for example) while updating the query data store as a background process which allow the entire system to stay stable under high degree of stress.

In other words, once we have split the responsibilities of the system up so we don’t overload the responsibilities of a single model to be both read and write capable, we are in a much better position to shape the way we handle our software.

Print | posted on Monday, January 25, 2010 12:00 PM

Feedback


Gravatar

# re: Encapsulation is the enemy of the user interface 1/25/2010 12:58 PM Roger Alsing

IMO don't mix up CQS with CQRS. they are two vastly different creatures.

CQRS is Greg Youngs idea with a command model and a query model where you can have queries for a certain gui.

CQS intends to make it possible to make pre/post/invariant checks in DBC without changing state and thus breaking already evaluated conditions.

There may be commands and queries in both cases, but the problems and contexts are not the same.


Gravatar

# re: Encapsulation is the enemy of the user interface 1/25/2010 3:31 PM Fred

I don' know...one day the slogan is "keep it simple" and the next day "let's bring in another abstraction and use two different models". If it comes down to the definition of CQS:
“every method should either be a command that performs an action, or a query that returns data to the caller, but not both. In other words, asking a question should not change the answer”
i totally agree with it. But it doesn't necessarily mean that you have to use two different models. If i look at the following post
(elegantcode.com/2009/11/11/cqrs-la-greg-young/) i would say it is completly oversized and brings a lot of problems if it comes down to maintain the resulting software. I agree that the requirements of the ui never should affect the domain model. Building a query model in that case to satisfy the requirements is ok, but only if needed and not as general approach.


Gravatar

# re: Encapsulation is the enemy of the user interface 1/25/2010 4:23 PM Rafal

Agreed. Artificial separation of the 'model' and 'view model' leads to duplication of logic and lots of boilerplate code to generate data transport objects. It's much better to allow the use of ORM-generated DAL in views + some smart ambient session management.


Gravatar

# re: Encapsulation is the enemy of the user interface 1/25/2010 8:28 PM Kyle

Who are you agreeing with, Rafal? :)

Yes, development is much more productive after understanding CQ(R)S. I love mixing them together like an alcoholic drink.


Gravatar

# re: Encapsulation is the enemy of the user interface 1/26/2010 7:39 AM Steve Py

Depending on what you're writing, avoiding DTOs can be wrought with adding a whole level of complexity integrated in the code that matters. Data-binding is the rage. Restricting actions available to users is easy; restricting views available to users is easy; but restricting specific details of data transferred to those common views... That's where things can go pear-shaped. I hate the thought of introducing code into views that essentially says "oh, I just won't show that."

I'm not sure I'd go so far as to introduce a separate models for view vs. update. I do like to define DTOs specific not only to views, but to things like user roles. IMO a view needs to remain ignorant of the business entities, but I guess that's why I tend to think more MVP/MVC rather than MVVM.


Gravatar

# re: Encapsulation is the enemy of the user interface 1/26/2010 10:37 AM Frank Quednau

Yes, darned users, always want to interfere with my beautiful coding with silly UIs, Command Lines and *gasp* API calls.


Gravatar

# re: Encapsulation is the enemy of the user interface 1/26/2010 1:23 PM jdn

Another advantage of splitting models is that you then don't need to map from your domain model to your view model (and vice versa). Why hydrate domain objects in the first place if you can create simpler objects in the first place?

Title  
Name  
Email
Url
Comments   
Please add 7 and 1 and type the answer here: