MVC Pattern Language (Part 1)
MVC Pattern Language (Part 1)
People seem to have forgotten the original intent of MVC. Let's refocus on what the creator had in mind — bridging the gap between code and users' mental models.
Join the DZone community and get the full member experience.Join For Free
Atomist automates your software deliver experience. It's how modern teams deliver modern software.
There seems to be a lot of misconceptions related to MVC. Some consider it a technique for code reuse, others think it’s how you group classes in web applications, and some have even mistaken it for the frameworks that claim to support the pattern. In this post, we’ll take a look at a paper written by Trygve Reenskaug and try to figure out what its original creator really means when he talks about MVC.
MVC Pattern Language
The first two sentences of the abstract already shed some interesting light on MVC:
MVC was conceived in 1978 as the design solution to a particular problem. The top level goal was to support the user’s mental model of the relevant information space and to enable the user to inspect and edit this information.
I intentionally emphasized the part about mental models, as this is a central concept in MVC. We’ll be talking about these a lot in this post. In case you’ve never heard about mental models before, here’s a nice quote by Jay Wright Forrester:
The image of the world around us, which we carry in our head, is just a model. Nobody in his head imagines all the world, government, or country. He has only selected concepts, and relationships between them, and uses those to represent the real system.
To combine the two quotes together into something digestible: The original goal of MVC was to create a piece of software that resembles the user’s internal image of a certain problem space and allow the user to interact directly with that image. (Was that digestible?)
25 years after Trygve Reenskaug presented the idea of MVC, he wrote a paper called The Model-View-Controller (MVC) – Its Past and Present in which he explores other ideas that support the original goal and combines them into an MVC Pattern Language.
In this two-part article, I’ll go over each of the patterns it contains and try to briefly explain them in a friendly way. The goal of this article is not to duplicate or rewrite the original text. I’d rather like to spread the original idea and inspire further reading.
1. Integrated Domain Services
Most, if not all, enterprises work in multiple (sub-)domains, e.g. finance, controlling, customer relations, etc. The whole system used by the enterprise has to be somehow integrated together.
Instead of creating one huge application that supports all of the domains, we create separate ones per each of the (sub-)domains. Reenskaug calls these applications domain services. Each of them should be tightly integrated internally but loosely integrated to other applications.
This pattern should resemble the microservices architecture style that’s been very popular lately and the bounded context pattern known from DDD. At the same time, as we’ll see in the next pattern, a domain in the MVC understanding does not necessarily have to match a bounded context in DDD.
2. Line Department Owns Domain Components
A single business domain can be handled by multiple departments in an organization. Each of these departments may have different needs, which in turn might lead to compromises when designing the application.
The pattern suggests splitting a domain service into domain components that match the departments’ responsibilities inside an organization. Then, a department is given full authority inside its component. To coordinate all components together, the pattern suggests the use of interfaces.
While Integrated Domain Services resembled a more coarse-grained flavor of DDD bounded contexts, this pattern seems like a more fine-grained version of it to me. As Trygve Reenskaug points out, going too fine-grained with this can make the organization more dependent on certain people and their personal characteristics. Thus, the whole organization might become more fragile and harder to change.
3. Mental Object Models
As I probably failed to explain in the beginning of the post, to make information systems more friendly and comprehensible for the users, they should be based on the users’ mental models. Building a mental model is hard, as it requires users’ active participation and understanding of the modeling language.
The solution suggested in the paper is to build a modeling language based on the concept of interacting objects and, ultimately, making the modeling language become the programming language itself. Given such language would be sufficiently easy, the users could design parts of the applications themselves.
Basically, it’s the same old problem over and over. We can’t go inside the users’ heads and so we’re doomed to misunderstand what they mean and want. Then, before we get everything right (if that’s even possible), the requirements change and the process starts over and over. Maybe instead of studying mind-reading, we could create tools that would allow users to model the program themselves. Ah, those programmers’ dreams!
4. Personal Information Systems
Although splitting a system into domains is a good idea on the back-end side of the system, the split is not that obvious on the front-end side. An individual might have a job that requires data and functionalities from multiple different domains. We want to provide him with an integrated information system, in which he can do all the tasks assigned to him.
To do that, we provide the individual with tools that allow him to perform all of his tasks using a personal computer. Under the hood, each of the tool uses domain services.
Considering the fact that companies and job responsibilities rapidly change, we need to ensure a fast way of providing new tools or new combinations of information. This moves us back to the programmers’ dream zone which, in this case, is (semi-)automatic tool generation.
5. Domain User Matrix
In the previous pattern, we’ve seen a discrepancy between an individual and the domain services. That discrepancy can go even further – the domain services might not match his mental models at all. He might be thinking in different objects than actually exist in the domains.
In such case, we can create a layer of business objects on top of the domain components that will bridge the gap.
The business objects look to me like object roles and contexts from the DCI architecture. These are also supposed to match the user’s mental model and orchestrate the domain under the hood. Also, as Trygve Reenskaug points out, the presence of business objects might cause logic to leak between them and the domain components they use.
Summary of Part 1
In this part, we covered a lot — from the deep corners of domain services and their components, up to the users’ heads and their mental models. We talked how the two don’t necessarily need to match together and how to bridge the gap using tools and business objects. In the meantime, we came across two particularly cool ideas that have not been implemented widely enough yet – modeling languages for the users and (semi-)automatic tool generation.
In the next part, we’ll look at the lower level patterns in the MVC Pattern Language, which will allow us to bridge the gap between the user’s mental model and the tool even further.
Published at DZone with permission of Grzegorz Ziemoński , DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.