As described on my home page, while developing recreationally a GUI-based application I was puzzled to find no well-established framework to help me. This page is intended to explore why this might be the case, and maybe propose a possible solution to the problem.
Think of graphics-based programs or word processing. All major graphics APIs are based on a conceptual framework so well-established that it is shared even by commercial rivals: PostScript
are slight variations on a theme. I don't know so much about the innards of word-processing, but it's striking how the content of say a FrameMaker
MIF file maps onto the JavaSwing
text APIs. In both cases there are agreed underlying concepts that no one argues about, combined with fully-developed implementations that anyone can use, even if they don't fully understand the concepts themselves.
There is no such clarity and stability with ModelViewController
(MVC hereafter). There is general agreement that it is a powerful concept, but general disagreement as to everything else: what is or isn't an implementation of MVC, whether MvcIsNotObjectOriented
and how far this matters, and so on. The discussion is sometimes conducted at near-religious levels of fervour, which suggests that clarity and stability may still be some way off.
And look at the major APIs based on MVC: JavaSwing
offer substantially different interpretations of how the core concept should be turned into a practical implementation, compared with the underlying similarity of their graphics and word processing equivalents.
That MVC is a very powerful paradigm, indeed an indispensable one, is demonstrated by the seriousness of the APIs based upon it. But the sheer variety of ways in which it is interpreted suggest strongly that MvcIsNotImplementable
as it stands.
Does this matter? Perhaps not, since the various intepretations of MVC all enable useful programming to be done. At the same time each represents a poor match to what a simple programmer like me would like to use, being in some respects too elaborate and in others rather incomplete. There seems to be no straightforward, reasonably complete framework available to someone who wants to create simple MVC-based applications. -- DavidWright
I'm not sure what you're saying. Are you defining "implementable" as "having only one method of implementing"? If so, there are plenty of data models that are "not implementable". Perhaps you're conflating "models" with "patterns" - models, by their nature, are abstract and lend themselves to a multitude of implementations. Patterns describe at a lower level how they are implemented.
I will concur with this statement from a practical sense. There seems to be no concrete guidance in delegating code segments to "Model," "View," or "Controller." While I have seen many people claim they were doing MVC, I often found upon detailed review that code assignment was almost random and seemed more geared to preserving Model, View, and Control source files than providing any actual programming benefit. Most programs would benefit from a 1 or 2 level model instead of an MVC model. -- WayneMack
Recently, I have stopped altogether to refer to MVC as such. I rather prefer to have different layers of code, instead of adhering strictly to, say, MVC. And mostly, I find that MVC is just a special case of Layered Programming having 3 layers. Instead, I now divide my code into different layers on a case by case basis. MVC, in some cases, causes the programmers to define Model/View/Controllers where it is not actually needed. This ends up in so called over-engineering of applications where each module has MVC which in turn has MVC and so on. -- vhi
The force that separates the View from the Controller is not as strong as that that separates the Model from its rendering. In the case of Smalltalk-80, where MVC first found expression, I believe the View and Controller were separated mostly so that their responsibilities could be well factored into single-inheritance hierarchies. This force is not uniformly present in different systems, so systems vary widely in how they factor Views and Controllers. -- WardCunningham
This sounds suspiciously like the View/Document model that MicrosoftFoundationClasses used. While I don't really like MFC's implementation of it, I've used the model successfully in a number of non-MFC applications. I've found that it's significantly more practical to implement (and more importantly, extend and maintain) than MVC. But then again, when you strip it down to View/Document, isn't it just a special case of ObserverPattern?
The responses above (while very welcome) were contributed before I had concluded my argument, as follows.
Let's try to be more specific about what our simple programmer might look for in such a framework: what should it offer if it is to be as useful as one of the standard graphics or text-editing frameworks? The programmer is creating an application that interacts with a user, so a good starting point is what this user wants to do. (It's interesting that MVC is often discussed as a solution more to programmers' problems than to users'.)
- Is it? I don't think that's true. The best part of it is precisely that it separates 3 things that the user may want separated, as is especially clear in accessibility applications, e.g. where a radically different kind of input or output device is used for I/O by a handicapped user.
- While important, perhaps accessibility is more a console issue (see below) rather than a core design concern.
To put what the user wants in an object-oriented way: the application creates objects containing domain data, the user wants to view (literally or metaphorically) and edit this data. The application must provide something that allows such viewing and editing; this something is commonly called a user interface but let's call it a surface
. In the most general terms, the user will expect the surface to provide
- information on the current state of the application and its domain objects
- means of sending messages to change this state
While this contract may appear too general, it does provide a clear test for proposed implementations. Thus a surface could be implemented as the complex GUI of a photo-editor or the simple one of a mobile phone, by a set of server pages or the keypad-driven menus of a voicemail system. Or by smoke signals, or messages tied to carrier pigeons, or the beat beat beat of the tom-tom - any detail design that fulfills the basic contract of allowing the user to communicate with application objects.
The attentive reader will also notice that by implication a surface just jumbles up under another name the well-known elements of model, view and controller, but in a sense that is just the point. Interaction with an application must be transparent to the user; the difficulty is to abstract transparency in a usable way. The MVC paradigm is certainly going to help, but the need for transparency is another way of saying that MvcIsNotImplementable
Perhaps those pretty triangular MVC graphics conceal as much as they reveal. MvcIsNotImplementable
because the model is an object
but view and control are functions
. The only generalizable implementation of the three concepts is as two objects, one allowing the user to access the other:
Object newViewAndControlSurface(int type)
This division of course is more or less what MVC-based widget sets such as Swing actually make internally; it's just so hard to disentangle the model from the surface clutter.
Finally, while focusing primarily on the user's needs we shall certainly demand that our framework make some provision for the programmer's. A surface must allow the user to look at and talk to the application and its domain objects, but we really, really don't want to have to mix up domain code with surface code (as for instance certainly happened in my early attempts to use JavaSwing
). Any practical implementation of the basic surface contract must make it as simple as possible to keep domain and surface code apart, and probably should enforce such a separation.
So at the topmost level our hypothetical framework should
- enable the construction of an interactive surface which exposes an application and its domain data to the user
- facilitate (maybe enforce) the separation of surface and domain code
It would also be nice if it could be used on top of arbitrary domain code and implemented for any platform in any (object-oriented) language.
Descending finally to a more practical level, the surfaces that a simple programmer mostly wants to construct are those of GUI-driven applications, so what should a framework offer that is specialized for this task? I would suggest an API that
Yep, I HaveThisPattern.
- allows construction and maintenence of multiple views/widgets for any domain object
- doesn't mind where widgets appear, preferably separating layout details from underlying control logic
- shields the programmer from platform event handling, and from all its own plumbing and housekeeping
Any other suggestions?
[One year later] None having been received, I went ahead and produced a framework to this spec, introduced at http://superficial.sourceforge.net
MVC is implementable. There are thousands of implementations. I think some of the confusion on this page comes from viewing Java's Swing libraries as "MVC-based". They aren't. They provide some tools to support building MVC structures (and other tools to confound the same task). Swing is not an MVC structure waiting for the programmer to customize the different layers. It's a set of tools that can be used to build an MVC structure. See PeterCoad
's critiques of Swing (specifically the observer stuff) for ways to avoid the parts of Swing that make MVC more difficult.
The thousands of implementations are just what I'm complaining about. Someone once observed that the more solutions are offered to a problem, the less likely it is that any of them will work. There has to be a reason why after more than twenty years no general purpose solution has emerged to the problem of implementing MVC.
MVC is not a problem waiting to be solved. It's a design pattern. There are millions of instances of the "Light on two sides of every room" pattern. That doesn't make it an unsolvable problem. That makes it a pattern.
[I think the point is that most of those "thousands of implementations" are MVC in name but not in fact. In fact, it would be interesting to see a list of high quality implementations that truly follow the MVC pattern well. I was thinking recently that there's been an awful lot written about what constitutes a "good UI", but for all of that puffery and punditry, it's very hard to think of examples of 100% good GUIs, MVC or not.]
If the point is that folks try to apply the MVC pattern but fail, then I agree. I think most of the blame for that lies in the way the pattern is taught. It comes from one perspective on one type of GUI, but it's taught as if it should be applied to all GUIs. There are alternate GUI patterns that work as well or better in some circumstances, but they aren't as widely known. When someone naively stumbles onto one of them they may feel they have failed to apply the MVC pattern.
And I can think of hundreds of good GUIs, but I probably have lower standards than you.
- Well, for instance I have strong criticisms of each of the Microsoft Office components, of Adobe Photoshop and Illustrator, of every GUI email program I've used under Windows, Unix, Linux, and Mac, and of each of the major components of Gnome and KDE, yet I've heard lots of people rave about how wonderful the GUI was, in each of those cases. Are any of the hundreds you're talking about ones that random people like me might have seen?
- Yes, I'd probably classify all of those (except the Adobe GUIs) as "good". As I said, I probably have lower standards than you. If you can't think of any examples of "100% good GUIs", what makes you think such a beast exists?
- Because in some cases the biggest problem is lack of a single feature, such as how to find tings. Say that I know feature X exists in a given app, but I can't remember how to get to it. Name a complex app where you can nonetheless find out e.g. which sub-sub-sub-menu implements X within 30 seconds of searching for it.
- Microsoft Word. The help system is excellent. Just today it taught me how to convert footnotes to endnotes, and I didn't even know what an endnote was to begin with. What make you think that a problem of this type has a better solution? You can't display every feature of an app like Word all the time. There simply aren't enough pixels.
- (A) I'm not talking about help systems. The one for Word is good in some ways, like if you want a tutorial on how to convert footnotes to endnotes. Even it utterly sucks if you're searching for a term using the "wrong" terminology (e.g. because you're thinking of a synonym), or if they forgot something (happens all the time) - but primarily, you're NOT talking about a 30 second process, if you already know you want to convert a footnote to an endnote, but you forgot how.
- (B) Microsoft Word itself is nice when it works, but it is well known to be such a botch that expert users frequently must give up completely on what they wanted to do, and just work around it by doing something else, or even by copying text into a fresh document - essentially starting from scratch. This is quite common; if such a thing has never happened to you, then you're lucky. Anyway, botched functionality is a thousand times worse than a faulty GUI, so...
- In other cases, the missing features were well-known in other high-profile apps long ago, but didn't get included due to NIH wheel re-invention. People don't bother to learn from history. Minor example: only a few GUI mail programs allow sorting by original-order-received. They seem to think the mail timestamps are good enough. They allow sorting by a number of criteria, but it's all ad hoc.
- Widgets are rarely thread-per, so that if you need to fill in info in a popup dialog by searching for info in some other widget, you're out of luck, it can't be done.
- The classic GUI bloopers tend to be less universal, although some form of them does tend to pop up randomly somewhere even in major apps.
I started this page from a desire to know what others felt about this problem, and I've not been disappointed. Here are some further thoughts.
- MVC is ... a design pattern
- If a pattern is a generalized practical solution to a well-understood problem, then maybe not. MVC is a powerful paradigm describing what's going on when people use interactive programs; we may have tried to apply it too directly to program design.
- There are alternate GUI patterns
- Perhaps these are less alternatives to MVC itself than alternative approaches to the implementation problem. For what it's worth, mine is now at ModelTargeterSurface.
- hundreds of good GUIs
- The power of MVC is that it applies as much to a command-line interface as to a GUI: a surface is a surface whether it's based on widgets or smoke signals. On the other hand, MVC says nothing about how surfaces should be designed for usability. A poor surface design could be implemented with perfect MVC SeparationOfConcerns; a good one could have model and surface code completely jumbled up under the hood (though it would probably be buggy).
One thing I'd love to know is how the big apps are designed under the hood: MicrosoftWord
. Is this documented anywhere in WikiWorld
- I doubt it, for two reasons: proprietary internals don't get discussed much, and also, they are almost certainly very ad hoc, rather than following a clean model. Which reminds me of one of the few really clean systems: Interviews.
Looking at surface (user interface) design as a layered problem, it's interesting how the problem domains of the different layers are more or less well understood:
- Abstract design, usability
- For better or worse, largely settled; the last burst of innovation was with the W3 explosion. Anyone designing a GUI or website must now bear in mind user's expectations based on experience of other apps. Mobile phones seem to have settled as a subset of GUIs.
- I've done mobile GUIs, but I'm not quite sure what you mean. The limited screen real estate makes it a real challenge, but it's not like we just settle for that as lowest common denominator and do the same thing on desktop screens. Please elaborate, maybe on MobileGui?
- Platform widgets
- Completely settled in terms of the general solution, with minor skirmishing about implementation details; for instance the JavaSwing and JavaSwt frameworks differ primarily in things like performance, portability and completeness.
- What is it that is settled? You mean, like the way Java uses native widgets vs not, or what? I mean the basic mechanics of event loop, dispatch queue, paint thread, keyboard and mouse input. Just look at the number of type names that SWT shares with JavaSwing/JavaAwt.
- Underlying mechanics
- Settled. If you don't understand what MVC is about, don't try to construct a non-trivial interactive application.
- Implementation architectures
- Still wide open with almost no agreement even on the problem, let alone the solution.
MVC as Defined in the Patterns Book
I believe the rationale of MVC as described in the Patterns book is to provide synchronization between multiple live views of data. If data is changed in one view, the change needs to propagate to all of the other views. This tends to be a rarely encountered case, as most designs intentionally avoid multiple live views. Few programs are written that actually would require the abstraction that MVC provides. In the vast majority of programs, single simultaneous views are the rule, providing little need to isolate a separate controller. Most claims of MVC use are merely cases of jumping on a buzzword bandwagon rather than architectural need or advantage.
Why do 'most designs intentionally avoid multiple live views' when these can add greatly to function and user-friendliness? I'd guess it's because they are hard work to code from scratch and there is no standard API for creating them. There's no need for a text editor to avoid character formatting, or for a graphics app to avoid anti-aliasing: they're part of the standard APIs. The puzzle remains, where is the standard API for MVC?
- What would it mean to have such a standard? What's an example of what one could look like? Such a thing would be more a meta-API.
Most designs are targeted at one user at a time and a single user can only pay attention to one thing at a time. There is simply little benefit to having two screens of the same information side by side. Users may want to switch between views, but rarely need to look at two views simultaneously.
- It does happen. E.g. CAD.
The question, I believe, is not whether MVC can ever be desirable, but whether it should be applied as a general solution. My contention is that there is rarely need for the capability supplied by MVC. Applying MVC where it is not needed requires one to make method allocations based on something other than the needs of the program. The result is program design driven by folk lore and decisions that cannot be discerned from the code. I would describe that situation as "code complexity." However a good API can hide the complexity for those who don't need it. For instance the AWT paint system always delivers a Graphics2D context, but you can ignore all the extra features and use it just as a plain old Graphics. Or you could have pluggable functionality as in EclipseIde or the Swing text editor framework.
There are probably two different items for discussion. One is "How often are multiple, peer views desirable?" and the other is "Does use of MVC where multiple, peer views are not intended increase complexity?"
A single user can only pay attention to one thing at a time, but often needs to view it in different ways at once. The API would enable UI features such as those of the big apps, which all do multiple live views eg
- Excel - split the window in two directions, have two windows showing the same worksheet
- Word - split the pane to edit two regions of the same document at once simultaneously; open print layout (which is editable) and outline view windows on the same document
- CorelDraw - view the underlying hierarchy in the Object Manager while editing in the main graphics window.
- EclipsePlatform? - (usually) reflect code changes automatically in browser views.
[Aside: Removed the rference to Word and "open print and outline view windows on the same document." as this does not appear to support the author's argument since Work print preview is non-editable and blocks switching between print preview and other document views. This note is added merely to highlight the change and allow the original author a chance to correct or reinsert the text if he deems it appropriate.]Thanks for spotting the ambiguity, amended as above.
The programmer should be able to define an application in terms of objects wrapping or defining:
- Content - domain data and logic
- Views - how content can be viewed eg print or outline view
- Viewers - surface elements such as text areas, graphics planes, tree viewers, that can host defined combinations of view and content
The framework should provide for
- Selecting and editing content in a viewer
- State management ie undo/redo, load/save at the content level
- Updating all viewers as content changes
There should be no limit on the number of viewers for any given content; views should be shareable between viewers
eg so as to zoom both parts of a split pane at once.
Multiple live views is probably a complex special case of multiple widgets giving view/control of the same data.
I believe the difficulty with MVC arises with the placement of business logic within the model. There is also a 3-tier model of user interface, business logic, and data store. I think a lot of confusion arises from overlaying the latter model with MVC. They are really two different things. -- WayneMack
Yes, MVC may best be regarded as a master paradigm for describing user interaction within an application with objects which may themselves be tiered - the Chinese boxes/Russian doll effect, further proof that everything is a tree:
- Application - complete software object that allows a user to view and edit domain data
- Surface - abstract user interface defining how abstract model elements are to be viewed and controlled; how the user perceives the application
- Console - provides the concrete user interface, conceivably a teletype (hence the name); usually platform widgets running in event loop; or web server pages?
- (?Targeter - handles one-to-many relationships between model and surface elements as described in ModelTargeterSurface)
- Model - exposes abstractions to the surface based on underlying domain data and logic; probably also manages state i.e. data retrieval and storage, undo/redo
- Domain (business) objects and logic created from, and persisted as, domain data
- Domain data store - proxy for file system, database
I may be missing your point, but I probably would describe MVC as a master paradigm for describing the interactions of views among themselves. It is primarily a messaging model based on the flow A View -> The Controller -> The Model and All Views. I think it is when one tries to overlay additional functionality (undo logic, for example) that confusion arises. The distinguishing concepts of MVC are: multiple views and the insertion of a controller between Model and Views. The allocation of functionality among Model and Views is simply outside the pattern.
) contribution to this opinion fest is that you cannot implement true MVC unless you have exclusive control over everything relavent to the GUI.
Smalltalk does this, because the whole GUI is itself coded in Smalltalk. However, in most other GUI environments, the function of view and controller are conflated into a widget.
For example, X11 treats InputOutput?
as both drawables
(views) as well as event sources (controllers). Therefore, in architectures so constrained, it may be more optimal to use DocumentView
architecture instead of a true 3-way split of MVC.
The exception to this, of course, is if you choose to override your platform's host UI functionality. For example, in X11, you can define event sources as InputOnly?
windows, leaving the top-level window as just a flat surface on which you can draw however you please. Depending on your X11 widget toolkit, this is a viable solution to getting the full 3-way responsibility split. There is even some logic in going this route for X11, since the only "default imagery" you can leverage for windows is a bordered box. In Win32, this is subtly different -- you have different classes of objects (buttons, checkboxes, et. al.), each with already-existing behavior, appearances, etc. If you wanted to override the GUI, you would have to do so in a manner that mimics the remainder of the environment as closely as possible. This takes additional effort, and it will never be quite perfect.
The only time "MVC" becomes relavent in such environments is when you're aggregating entire *gestures* into commands (e.g., gesture-based navigation in Firefox). However, at the level of most GUI definitions for a program, MVC as such
cannot be implemented due to architectural limitations of the underlying GUI libraries.
Should 'MVC" stand for Multiple Visualization Concepts?
Its almost like fractal patterns, but finite. MVC is just the tip of a greater implementation, unless you consider everything that calculates logic gates a model, everything you see is a View and everything that unites the two is a Controller. So I have to disagree and say it is implementable, anything someone can slap an anagram on is implementable, just the concept changes with who you talk to.