Here's a short overview of four major user interface patterns in their original form, put together and illustrated. A bit of information is added to patterns (with notes to highlight these additions) to show a slightly different viewpoint and different ideas.
The original Model View Controller pattern looks like this:
Please note that 'Data Logic', 'Presentation', 'Input', and 'Output' are added by me.
Also please note that in some documents that I found online, View is passing input events to the controller, it's not directly given to controller.
The original example is a WYSIWYG editor in which View is the editor, Model is the data of type string behind the editor and the Controller is responsible for handling user (mouse and keyboard) inputs. Both View and Controller change Model. If Controller changes the Model it needs to notify View about the change.
The triad of MVC seems to be created to overcome limitations of SmallTalk (older technologies didn't have model UI capabilities) and complexity of the application.
This pattern seems to be an attempt to complete MVC to handle more complex scenarios.
How exciting! This patterns introduces two interesting concepts, first, 'Presenter' (Which I placed in a category which I labeled with 'Application Logic') and second 'Selections' (which is now part of the category that I marked as 'Data Logic').
Model in this pattern is a wrapper around Data. (Persistence, access and management isn't shown in the documents that I found so I assume that it'll be considered part of the Model too).
Selections are part of the data upon which operations will be performed. (Imagine a list of users, SelectedUser becomes the 'Selection' in this scenario.)
Commands are operations on data (Command pattern) and are given to user interface controls via 'Interactors' to be invoked when needed.
Interactors map user input to specific commands (magine MenuFileOpenInteractor.)
Presenter is the glue between Presentation and Data Logic. In the IBM documentation is stated: The role of the presenter within MVP is to interpret the events and gestures initiated by the user and provide the business logic that maps them onto the appropriate commands for manipulating the model in the intended fashion.
Model is like previous patterns.
View has a major change here. It handles both input and output and completely decouples user interactions from other layers.
Presentation Model "pulls the state and behavior of the view out into a model class that is part of the presentation. Presentation Model is an abstract of the view that is not dependent on a specific GUI framework. Several views can utilize the same Presentation Model."
MVVM is almost identical to Presentation Model. The main difference is a systematic mechanism for binding View to its Model using Binder.
ViewModel reason and issues
Let me start by MVP pattern. Reality is that applications don't operate only on 'Data' and 'Selection of data'. Programmers have to handle UI data as well. By 'UI Data' I mean the data that is created as a result of composition of 'domain logic' and 'presentation logic'. For instance if we come to the conclusion that we need to highlight a piece of information on the screen under certain circumstances (this is the decision of the domain/business logic) with red color, then the 'red' color is what I call 'UI Data' and how we orchestrate UI widgets to achieve this goal is what I call 'presentation/UI logic'). Thus I see more layers and state in a real application.
'Red' color in here and such UI data is maybe the reason for introduction of 'ViewModel' in MVVM.
Yet MVVM introduce other problems in my opinion. ViewModel is a class with very high potential of violating first principle of SOLID. SRC suggests that a class should has only one reason to change, yet if a view is a bit complex, which most views are, ViewModel becomes responsible for storing irrelevant data and behavior in one class. If you have a MainViewModel you probably know what I am talking about. The pattern even suggests that the ViewModel can handle more than one view. The fear of dealing with too many objects (like PAC pattern) that are hard to maintain probably had been the reason for that idea I guess.
I believe that MVVM is a good choice for multiplatform applications with identical GUI, because of what it separates; View from its state and behavior, thus making it easy to connect ViewModel to another identical view created by a completely different technology, but this goal, seems not to be the reason for using MVVM in WPF.
It's worth mentioning here that often times ViewModel class is logically coupled with the GUI controls (Control types can affect ViewModel property types), thus it will not be easy to reuse it for a different type of View.
I believe, MVVM results in an almost view-independent code behind file, located elsewhere in application structure, I'm just not sure if it's worth the hassle for the purpose of most WPF apps out there that are targeting only Windows and I truly doubt it decreases maintenance costs, yet I have no data to back this claim.
The idea of a code-behind class with bound member variables, isn't new at all. Nearly ten years ago I was coding with MFC, adding member variables behind
CDialog classes bound to controls using
DoDataExchange technology and
CWnd::UpdateData method. It wasn't resulting in clean code and it was hard to maintain. Maybe the reason is that user interface in its core is more a combination of 'Data' and 'Events' rather than 'Data and behavior' which a class is. Anyway, I like the new movement towards finding better solutions, MVVM being one of them and I really love the ease that WPF bindings brings to this process too.
Separation of concerns
There exist very separable concerns that almost all applications have some or all of them. I call these 'Application Services' including but not limited to health monitoring, event and error logging and reporting, automatic updating, support for visual themes, security concerns like application activation, application status history and status management, packaging and publishing, globalization and anything else that is responsibility of an application for the application itself (not for any specific domain) or any of the services that application provides as a host to a specific domain logic. I think “Enterprise library” started with the idea of separating such concerns.
Apart from these services, in my mind an application is made of many layers, like: Data Storage Logic, Data Access Logic, Data Structure Logic, Data Processing Logic, Application non-UI Logic, Application UI Logic and application UI technology. Almost where ever there is a logic, there is data associated to that logic too. The problem is that often times these concerns are so tightly coupled that it seems impractical to separate them all for the sake of separation only.
Martin Fowler describes 'Separated Presentation' as “Ensure that any code that manipulates presentation only manipulates presentation, pushing all domain and data source logic into clearly separated areas of the program.”
I believe that domain and data source logic is what creates GUI elements we see on the screen. Why is there a text box with a label next to it, which reads “Email Address” on an HTML form? Because domain logic dictates that we need that piece of information to continue with the rest of the logic.
Therefore I question possibility of the idea of separating “all domain logic” from presentation.
Often times, in every little piece of the user interface of an interactive system, there exists an operation, executed upon specific events of the UI or of other operations, an operation which requires data from system database (Model if you will) or data resulted from actions of other operations, an operation which changes system data or view data or produces new data. This operation often is the result of existence of both domain logic and UI logic and makes it difficult to separate an application in layers like UI, Domain and Data.
Still a well-structured source code, which is the reason I love many design patterns and object oriented programming in general, is worth spending time and learning and maybe you dear reader, come to new ideas that can improve or change lives of all programmers in the world after learning these techniques. After all, that was why this article was created.
- June 12, 2013:
- June 18, 2013:
- Added comments to photos and tweaked Input/Output boxes.
- Added MVC Sample (C#, WPF)
- Fixed last history entry.