MVP just Visual Basic with "more wing nuts"?
16/04/09 10:57 Filed in: Dolphin | MVP | All
MVP was intended to be quite simple whilst also giving flexibility for better code re-use, and therefore maintainability, in GUIs. I suspect that, in some respects, we failed in the former aim based on the number of people who've had difficulties "clocking" MVP in the past. So, the first thing is; If you don't yet get it - you're not alone. Hopefully,the following discussion will help and not hinder in this respect.
Wasn't VB Great?
Think about Visual Basic (with which I assume you're familiar). What a great system for easily building simple GUIs by drag and drop. I won't hear a word spoken against it! Only when one gets to more complicated apps do cracks start to appear.
I call Visual Basic a visual component system. You have a toolbox of components that you can drag and drop and place on a form. You have text fields, check boxes, push buttons, lists and ActiveX controls. You can compose these in a container (the form) and write code behind each control or behind the form itself. Typically you can change the way a component looks by setting properties in the property inspector. It's all very quick and fun, but what happens if:
1) You want to change the "look" more drastically without affecting the underlying functionality of the control.
2) You want save a container with pre-built functionality and later re-use it inside another container or form. VB does not allow nested/hierarchical containers.
3) You want to associate more structured data with a control. Either with a normal control or a composite that you have created. In VB the data types held by controls are fixed and you can't really associate a specific data type with a form at all.
So these are the problems that MVP aims to solve. Typically, a component in MVP is represented by a Presenter. This is the "visual control" if you like. It has data associated with it (the Model) and an appearance (the View).
In MVP, Presenters are Components
In VB you build up functionality by composing components into a form or by adding code behind them. The equivalents in Dolphin are to build a new composite presenter or to subclass an existing presenter respectively. In Dolphin you don't build a composite by dragging and dropping like you do in Visual Basic; instead you create a subclass (typically of Presenter) and then add a #createComponents method to add the sub-components to it. Ideally, we would have a drag and drop editor to do this but, as yet, we don't and you have to code the assembly yourself.
So by creating new presenter classes you can create new components. For each component that you create you can (and, indeed, must) specify the data on which it operates (the Model) and the visual representation (the View) on the screen. Often a model is just something simple like a text or number value (a ValueModel). Other times it is a collection of things (a ListModel) and sometimes it is more complex still (any Smalltalk object you can think of). A view needs to be drawn for each component with the View Composer.
I think one of the confusing aspects of Dolphin's MVP for many people is the use of the View Composer. Because it looks like the VB form editor they assume it performs the same task - to assemble components. This is NOT what it does. One assembles components in code (by creating subclasses in the presenter hierarchy) but you specify how they look in the drag and drop View Composer. Designing the appearance (certainly the final appearance) will likely be the last step you take when building a GUI component. In VB it's the first.
Views are "Skins"
Because of this separation between presenters and views, the latter can existing in a completely different hierarchy from the former. Hence it is possible to have a fairly simple hierarchical structure on the presenter side that only reflects how the logic of the application works. We like to think of this as being like a schematic diagram. Electronic engineers use schematics to see exactly how a circuit functions without all the extraneous clutter of how the circuit design has to be laid out on a printed circuit board (PCB). It's the same with presenters and views; in the former, you can see the logic of the application without being hindered by the constraints of how the GUI will appear on the screen. Indeed, in many apps, it may also be advantageous to have several different GUI "skins" for the same underlying presenter logic. This is what the ability to associate many views with any given presenter allows you.
Views can have a completely different structure from Presenters
I've suggested that a presenter hierarchy should be as simple as possible; only enough to represent the logic of the application's interactions with the user. However, the view hierarchy can be more complex. Often this might be the case to allow for automatic layout functionality as the window is resized (via LayoutManagers). Because of the separation between view and presenter all this "visual fluff" can be done without clouding the logic in the "schematic".
Sometimes, you can even use this feature to arrange non-rectangular components, i.e. in MVP, a component isn't forced to live inside a rectangular box on the screen (an example of this is the use of the MethodBrowser inside a ClassBrowserShell - it holds the method list and the source pane in a non-rectangular area).
Should MVP be relabelled MPV?
Another confusion might be in the acronym, MVP. Model-View-Presenter implies a certain creation order but this is rarely how the design actually proceeds. Typically one will have some data, a instance of a Smalltalk class, that needs to be represented in a GUI. This is the Model and it usually comes first. Next is the visual component for interacting with the model . This is the Presenter and it is usually considered next. The View (the way of representing the model on the screen) is normally the last piece of the puzzle - if only because each view must have a presenter in existence for it to be attached to.
Often, because of the dynamic, interactive nature of Smalltalk, the design of presenter and view proceed in lock-step but in reality it's probably helpful to think of the presenter coming first, if only slightly. So, think Model-Presenter-View!