Over the years, we've developed a few patterns to deal with building user interfaces to programs and dealing with dynamic data. We've had Model-View-Controller (MVC), Document-View (DV), Model-View-ViewModel (MVVM), and a few more (for an exhaustive list, see Derek Greer's excellent piece covering the history and use of every presentation pattern you've heard of, and a few you haven't). Though I'm not going to cover all of these, I would like to start discussing the most popular ones. It amazes me given how much we've discussed these patterns over the years that we still regularly get them wrong in custom implementations.
The Document-View Pattern
The document-view pattern was once the preferred pattern used in Visual C++ development. Microsoft built the original Microsoft Foundation Classes around this pattern back in the dark ages. It’s not used much today, but it’s useful when you have simple data management needs. The problem with this particular pattern was the decentralization of data management logic, which tended to be spread around the document and view classes.
This pattern was originally built to address data view proliferation. Back then, engineers were building applications like spreadsheets, email clients, or word processors, and these were primarily rich clients running locally on some workstation. The more sophisticated applications had a client-server architecture with a data repository backend of some kind. Engineers were continually running into issues where they had to dynamically display the same data in multiple ways. Now, the MVC pattern would certainly have solved this problem too, but when the MFC designers adopted DV we didn’t have the kind of internet we have today. It’s very likely they weren’t aware of the pattern. They also may have felt it was too complex, and wanted a simpler data display architecture. Whichever the case may be, they used DV instead of MVC, getting rid of a separate controller class.
What Is It?
In the DV pattern, we have essentially two classes: a document class, which works as a model and an observer and can communicate with some backend repository, and a view class, which displays data and provides user data manipulation functionality. The document contains a reference to all the views, and each view contains a reference to the document, for a many-to-one relationship between views and documents. And it’s pretty easy to migrate from DV to MVC too, a definite plus. You can start with a simpler pattern and easily refactor to a more complex, powerful one if needed. More on this shortly.
Why Use It?
Well, it’s simple. It’s fast to build and easy to navigate.
It’s pretty disorganized. So the view object needs to not only render data, it also needs to handle data input. This can lead to bloated document and view classes, and a distribution of control logic across two separate classes, usually a bad idea. Realistically, this usually gets relegated to an aggregate object in more complex scenarios. And this, basically, is MVC. It also has circular dependencies, which are always fun to design around.
That's the description of the pattern. See Part II for a detailed example.