Model-Glue

This is a response to Jeffry Houser’s critique of Model-Glue. You should read Jeffry’s post before this one, as I directly respond to some of his points. To cut to the chase – me too, Jeffry, me too!

I’ve used M-G for two medium size projects. Like Jeffry, I can’t see a case where I’d use it again.

I couldn’t agree more about the event/view structure – this is just a global scope by another name, which as a way of passing variables takes us back about 40 years in programming language evolution. Yes, there are intelligent ways to use it, but the fact is that a robust mechanism for defining APIs already exists in the language (public function parameter lists) and a really great argument needs to be mounted for disregarding it. So does the rest of M-G mount that argument?

It seems to me that the heart of M-G is the implicit invocation mechanism. Essentially this is an event-driven programming model, and like all event-driven programming it supports very strong decoupling. At the point where you raise an event, you have no control [but see Brian’s comment below] over who will handle the event or what they will do with it. This is a powerful technique with applicability where system behaviour needs to remain loosely specified until load-time or even run-time (this is why you can change the menu structure in Microsoft Word while it is running). The tradeoff is increased opacity, increased debugging difficulty, and greater emphasis on good design – or to put it conversely, it’s much easier to make a mess of it.

As a programming model, it absolutely is not what I want when I’m setting up an average web app. 99% of the time I know exactly what controller function I want to invoke, I know exactly what data I need, and stating that with clarity is good design. Adding several layers of indirection adds no value at all – rather it greatly increases the risk of regression during future changes. As mentioned above, M-G tends to obscure the APIs of the various components rather than help define them. This is not to say everything should be hardwired. My beef with M-G is that it pervades the whole application, unlike techniques such as dependency injection and aspect-oriented programming, which let me introduce extra abstraction and complexity only where I get the payoff.

As a piece of software, M-G is a great achievement. It’s just the wrong tool for pretty much every job I have. The tragic thing is that, even if I did have to write a complex event-driven GUI, I’m pretty sure I wouldn’t be using ColdFusion to do it.

P.S.
A minor disagreement – I don’t think there’s anything wrong with the view having a dependency on the model. In fact it’s kind of absurd to think that a view can avoid having a dependency on the data it is representing. The important thing is that the model doesn’t have a dependency on the view. (Trygve Reenskaug’s original MVC pattern is instructive in this regard, although it’s not directly applicable to the web). So having to pipe all data via the controller is another layer of useless indirection. Having said that, there’s a fair bit of confusion about where the boundaries between the controller and the view are, so maybe this is just an issue of definition.

7 thoughts on “Model-Glue

  1. “I don’t think there’s anything wrong with the view having a dependency on the model.”

    It depends what you want to do and what your goals are and how much you care about reuse. In many situations, an argument into the view may be a value object. The value object is often considered a part of model. But, the view shouldn’t be dictating how the object is created, or where it comes from. Together (the view and the Value Object) create a defined API for the view.

    In a more strictly typed world, the view dependency wouldn’t be on a value object, but rather an interface which the value object represents.

    “In fact it’s kind of absurd to think that a view can avoid having a dependency on the data it is representing.”

    Every heard of the Flex Framework? There is a full set of UI Components built to handle any type of data you throw at it. They’ll work with XML, ActionScript objects, JSON, or even native data types.

    This is not entirely different than the HTML text input I’m typing into right now. It would be extremely limiting if this text box forced you to always enter in upper case and would only save data to a MySQL database through a PHP class. [or whatever].

    When building an application, you may not care about optimizing your views for re-use; which is fine. But, it isn’t absurd; it’s pretty common. We can do what we do because these ‘elements’ exist in a flexible, encapsulated way.

  2. Jeffry,

    Thanks for the comment. Perhaps to clarify a bit: if I have a view that draws a person’s profile (address, phone, etc) the model has to actually provide at least those data items, and conversely the view has to faithfully represent them (e.g. not represent the phone number in scientific notation). That’s tight coupling, it operates at semantic level and it’s not really avoidable. Can I reuse that view to represent something other than personal profile data? Probably not. Reuse of that view really is tied to reuse of the underlying model.

    In the case of a text input, the model is excruciatingly simple – a single string object. That model is very light semantically and can be reused all over the place, which is what makes that view component so reusable.

    I realize this probably isn’t what you have in mind when you say “model”, but I do think that model reusability is an important concept. And I guess what I react against is when people add layers of abstraction to “decouple” two things – a model and a representation of that model – that semantically must remain bound. Not saying that you are doing that, but rigorously removing model references from views can lead to that.

  3. “At the point where you raise an event, you have no control over who will handle the event or what they will do with it.”

    Can you explain the “no control” bit in that sentence?

    When I want to know what happens when my ModelGlue apps process an event, I simply look in my ModelGlue XML configuration file, and it tells me what messages (and hence what controller functions) are being invoked to handle that event. If that particular event is wrapped within an event type, then there may be other processes that occur before or after the specific behaviors outlined in the particular event, but again it’s no mystery what’s going on and I can certainly control each and every bit of it.

  4. We’ve use MG in many enterprise applications. At one point we were told by Joe or Dan, the folks in charge of MG, that we might be one the largest MG apps around. Believe me, we are no hacks either with most of us having 10+ years exp.

    There are several ways to break a view dependancy on the exact model data.
    1) Having the view use only simple variables copied from model objects into the view state
    2) Having a view only model and mapping data between the two models.
    Both of the above allow for better TDD since you can fake the view data all day long.

    Also one thing we do here is have very light controllers and multiple controllers. Then we have all the data requests to the model layer go through a broker or data handler. So the controller actually do not know anything about the model, just the broker. We can then front end that broker with any thing, like another MVC framework, web service layer, etc.

    I’ve not evaluated some of the newer MVC frameworks for CF but several years ago MG was one of the better ones out there. Its very configurable, you can set it up by configuration or convention, it does not try to be a everything and stays very true to the MVC and IoC patterns. Its still my go to framework.

  5. @Brian,

    Thanks for picking me up on that – you’re quite right, and I’d hate readers to get the idea that something random happens. The call chain is well-defined and discoverable. The control I’m talking about is control over how other programmers interact with my design. Maybe “guidance” is a better word. In this regard well-defined APIs and extension points are crucial. M-G places several extension points into every call chain. 95% of those are not needed and are actually undesirable, in the sense that I want tight control over what code executes in response to a given event. If these things were functions, I’d make them private. Events and messages, however, are all public and available for anyone to layer more stuff onto. You can compensate with team discipline and documentation, but that doesn’t change the fact that the framework gets in the way of expressing the design.

    @TJ (Ryan’s your last name, right?),

    I think MG would probably pay it’s way better on larger applications. Is that your experience?

    Good points re data abstraction. I’ve used all of these techniques myself. What I’m struggling with is to see these things as actually adding value as a general approach – as opposed to specifically where variation is anticipated and decoupling is needed. And they do need to add value, as they definitely have a cost, if only in complexity. I’d be interested to hear where you’ve seen the payoff.

  6. “Thanks for the comment. Perhaps to clarify a bit: if I have a view that draws a person’s profile (address, phone, etc) the model has to actually provide at least those data items, and conversely the view has to faithfully represent them (e.g. not represent the phone number in scientific notation). That’s tight coupling, it operates at semantic level and it’s not really avoidable. Can I reuse that view to represent something other than personal profile data? Probably not. Reuse of that view really is tied to reuse of the underlying model.”

    No, it does not have to be tightly coupled. As I previously stated, in a strictly typed world, the view dependency wouldn’t be on a value object, but rather an interface which the value object represents.

    The thought that the ‘UI Element” API is limited and discrete is probably true for most HTML components. For Flex components (Or WPF or other advanced UI Frameworks/libraries) the API can become incredibly dense and complicated all without attaching those UI Elements to a specific backend / data source. Going back farther, the number of things you could control in MS Access w/ VBA were astounding.

    That said, I think you are coming to this conversation with a very specific belief of what a view or view class is, which is accurate but not complete.

    As an aside, it’s a shame there is no way to subscribe to comments on this blog.

  7. Jeffry,

    I shall ponder your words. If you’d like to expand on “a very specific belief of what a view or view class is, which is accurate but not complete” when you get a moment that’d be great. Also you might like to check out my post specifically on this topic: http://lagod.id.au/blog/?p=199.

    In the meantime, I’ll try to rustle up a comment subscription plug-in. I had assumed that was just standard.

Leave a Reply

Your email address will not be published. Required fields are marked *