[Infusion-users] MVC and Infusion
antranig.basman at colorado.edu
Sat Jul 3 00:38:02 UTC 2010
Hi there Jonathan - these are really insightful questions and analysis
which I'd like to respond to at some length - although perhaps in this
mail I'll just give a kind of "potted summary" which might be a good
jumping-off point for further discussion and illumination.
The Fluid conception of what a "model" should be and how it should map
onto a design was derived from a quite broad consideration of how the
"MVC" pattern was manifested in various other environments - with
Smalltalk being clearly the paradigmatic one where it appears to have
originated. The concerns that you mention (unconstrained multiplicity of
relationships and separation of concerns) are indeed the crucial ones
which this pattern was conceived to address - and our slight
reformulation of it was made in the light of considering that its common
implementation style found "in the wild" generally fails to meet these
In particular, the one aspect of the style you mention, a "model base
class" is what we consider one of the crucial design errors that fights
separation of concerns. If there is any kind of such "base class", it
clearly must derive from the implementation model of a particular view
framework - which is obviously an error, since the purpose of this
separation is to avoid dependence on view-related concerns :) The
correspondence of "model objects" with the database or persistence layer
is a converse example of this kind of error - some kinds of MVC
frameworks manage to make both of these errors at once :)
It might seem impossible at first sight to avoid such an unfortunate
coupling but we think we are some distance along the road to a promising
solution. The key pieces of technology, or idioms that this relies on,
are firstly our basic "event" framework - which there is a jumpoff-point
in our "Concepts" section here:
These "events" are more general than those typically found in frameworks
since they impose no coupling on the target - there is no "event object"
framework or hierarchy, and to the target, the event signature is simply
that of an (unconstrained) function call. Clearly this relies on special
piece of technology is the "change applier" - which is described on this
This does the work of allowing a "completely general" body of "model
objects" (also see this in the framework concepts page) to function as
the model for a component, with all the facilities you would expect with
respect to one-to-many broadcasts etc. without actually imposing any
constraints or such "base classes" on the "objects" in question.
So where you see "apparent responsibility" within a view component for
managing updates to models and the resultant "apparent coupling", it
should in all cases be possible to drop down to a factored view in which
there is a view-independent piece of model state which is being
addressed, and a view-independent "applier" and associated events for
managing changes to this state and broadcasting updates.
It does have to be mentioned that not all of the Fluid components
currently delivered conform perfectly to this model, which is still
evolving over time - the next framework release will feature a much more
powerful ChangeApplier which will get rid of yet more code from the
problematic "C" element of the MVC triad. Many of the current components
were first implemented very early in our framework and are lagging to
various extents conforming with these kinds of ideas - but are being
actively upgraded over time :)
I don't want to sound dogmatic about any of these concepts, which are
very much a "work in progress", especially since they have not to our
knowledge met any parallels in any other existing "MVC" oriented
frameworks. In Fluid we regard the "MVC" concept as a promising first
factorisation of the structure of a user-facing application, but only a
starting point for more thorough work aiming at separation of concerns.
Your feedback or questions on any of this documentation or machinery is
really welcome, and we look forward to working with you on it :)
On 02/07/2010 16:23, Jonathan Smith wrote:
> Hi All,
> I am new to Infusion, and so I may be interpreting things incorrectly. If so, please excuse these comments. This is in response to this page:
> In the classical MVC design pattern, an object was called a "model" because it was an object-oriented model of a domain object and its behavior. The goal was to separate concerns about behavior (business logic) from the details of the user interface. You can think of controls as being the read-outs and leavers on a (potentially) complex but abstract machine called the model. In fact if you look at a Smalltalk image, the class Model is one that handles registering listeners and broadcasting changes.
> In the classic arrangement controls call methods to query visible state and modify model objects. Likewise when a model was changed, it would broadcast a description of the change to listeners. That way model logic would be all about the domain and would not have to reflect any knowledge of the specific controls and read-outs attached. Views and controls would be about visually interpreting and allowing the user to modify model state by calling public methods while not having to deal with the business logic. If you wanted a new view or control, you could write one and attach it without altering the model's logic.
> Infusion, on the other hand, by putting the responsibility of broadcasting model changes in the hands of visual controls (components) is introducing two issues: 1. It makes it difficult to have a many-to-one or one-to-many relationship between model objects, views, and controls, and 2. Separation of concerns becomes more difficult.
> 1. One-to-Many Relationships Between Models and Views
> For example in my zooming image viewer, there is an object called the Viewport that represents a geometric model of the portion and scale of the image visible to the user.
> a. Zooming and panning is a matter of changing the Viewport, then this change is broadcast to the visible components, including the view window, which will display a portion of the image at the appropriate scale. However the same broadcast also causes a change in the size and position of the little red rectangle over the thumbnail which shows the portion of the image being viewed. A single model object (the Viewport) has several controls which listen to change events and change their state when the model changes.
> b. Clicking and dragging the mouse on the thumbnail causes the scroll position to change and pans the image by updating the Viewport. (It does not, by the way, change the red rectangle indicator directly, since that is driven by changes broadcast by the model.) Similarly the Viewport can be changed by clicking the zoom in or out buttons, or dragging the selection rectangle over a portion of the view window (in zoom mode) or dragging to pan the image in the view window. There are multiple ways to change the Viewport object! The nice thing is that if you pan by dragging on the thumbnail the image moves as you do it. If you pan or zoom using the view window, the thumbnail indicator moves and changes size.
> 2. Separation of Concerns
> Every single line of code in Viewport is about the geometry of the view image and broadcasting changes. It is written with no knowledge of the thumbnail, the view window, data communications, or any other control. Instead it mainly deals with points, rectangles and affine transformation matrixes. This also yields a nice separation between the controls: the thumbnail navigates without worrying about loading image tiles, a TiledImageLayer worries about loading the images under the visible rectangle without worrying about the navigation, and so on.
> All of this became confusing because web frameworks made "model" synonymous with objects corresponding to database records, where the business logic is often implemented. The Smalltalk vision of a simulation model interpreted by multiple views and modified by user controls is still the cleanest approach. Having model objects without behavior moves the implementation of behavior closer to the specifics of the user interface.
> I am planning to start moving some of the image viewer and image annotation code into Infusion, and it would help a lot if I could have model objects with behavior and listeners. What is a good way to do that?
> Jonathan Smith
> Infusion-users mailing list
> Infusion-users at fluidproject.org
More information about the Infusion-users