MVC Question: What Should The Controller Pass The View?

MVC Question: What Should The Controller Pass The View?

Posted by Brad Wood
Sep 05, 2009 07:08:00 UTC
I think the bane of development planning can be those conversations where you personify your framework and start debating about what a service should "know", whose "job" a particular operation is, or what the handler should "care" about. This is one of those sort of questions, but I'll keep it brief since I'm more interested in your opinions than my ramblings.Here's the setup: We have an application built with ColdBox (MVC). The existing interface is all in HTML with a smattering of Ajax thrown in. We have been careful to maintain the separation of our model (services, beans, and DAOs), our controllers (All the ColdBox handlers), and our views (HTML output so far with a few proxies used by Ajax to return HTML or simple data). We are at a point in our application where we want to go back and rewrite a few pieces in Flex, and after that, some much larger portions. Our thought all along was that the magical separation of our views from everything else would aid in this since, in theory, the same service calls and handlers could return the exact same data back to any view; be it HTML or Flash. The first problem we are running into is the widespread interaction of our model with the views. For instance, we used the IBO pattern, so a screen listing a user's addresses would start in the addressList handler which asks the AddressService for the list of applicable addresses. The service creates an Address IBO, asks it to load itself via its DAO, and returns it to the handler. The handler, happily sets the Address object full and brimming with all its addresses into the request collection and asks the view to renders itself. The view, knows to look in the event's request collection, pulls out the address object and proceeds to loop over its members whilst creating the HTML table on the screen. This is just one basic example, but it carries one major assumption: The view will be able to understand and use anything in the request collection including CFCs. Now, instead of using an HTML view which is created in a .cfm file, I will need to call my handler via a proxy and return the data via my web service to the Flex front end. Of course, a CFC like an IBO cannot be passed to Action Script, so the data must be placed into a form that can be transferred easily like a result set. Here are a few problems/questions about that:
  1. The request collection is a struct containing any number of items the view needs. Should my Flex app make a series of atomic hits to the web server to get everything it needs separately, or should I return a struct back with everything all crammed in there?
  2. Massaging all that data out of the objects and into a result set seems like a lot of extra work; especially since my model layer just went through all the work of of building objects out of my result sets.
  3. Who should be doing this dissemination of data into a form palatable by the view? The handler? The proxy?
  4. Is it cheating for us to use CFCs directly in our views instead of only simple data (strings, numbers, result sets)?
  5. Was it silly of me to think we would be able to reuse handlers for both HTML and Flex views?
  6. Why do I keep wishing I had my CF model in Flex? It doesn't feel like just a "view", it feels like an actual client-side application that I've got to keep stupid because it doesn't speak CF.
  7. The little mapping of my result set to an array of Action Script objects seems silly to me. They're nothing more than glorified structs with getters at that point. Even if I mapped my user.cfc to a user.as object in AS it's not like I could call user.getCompany() in my Flex app and expect the company object to be lazy loaded in.
  8. Are we over-thinking this?
  9. What would Hal Helms do? Wait, don't answer that unless you're Hal.
  10. I promised I wouldn't ramble, sorry. *sigh*

Pedro Claudio

When you do a restructuring of this kind, you owe if liberate of the whole concept of previous vision, forget cleans the mind, and it work your mind with desktop applications that are inside the browser. Think of desktop and liberate itself of the web concept. Working thus all her interfaces will be coupled to any data connector. Regarding CFC, the kind conversion of given is transparent, do not worry, CF was worked for you if you do not worry with that, imagine the data going out from CFC and going to Flex naturally. I no longer can tell the same of a Struts, if there were no FXStruts, my life would have been a hell at the beginning of year.

Clint

I couldn't understand anything Pedro wrote, looks like spam to me ;) I'm also a Coldbox CF and Flex developer. Haven't tried to remote to cfc's or CB handlers from a Flex MVC like Mate or Cairngorm, you tried that yet? Are you guys using a Flex MVC framework? Any ways, I think you should read the <a href="http://ortus.svnrepository.com/coldbox/trac.cgi/wiki/cbColdBoxProxyGuide" target="_blank">Coldbox Proxy Integration Guide</a> if you haven't already. I'm not sure if it'll shed any light on your issues but it works. My problem is trying to conceptualize juggling two objects between CF cfc's and a Flex model. Am I supposed to create and use the object on the CF side then pass it into Flex where I have to again create an object in AS for it? Essentially creating 2 beans or 2 vo's, etc..

Brad Wood

@Clint: I don't think Pedro is spam. I think he just speaks Spanish a lot better than he speaks English. Look at his blog :) No worries, though-- I got the gist of what he was saying. Basically that you have to change your paradigm when you do Flex from a request/response "web" model to a desktop app "single load" model.

We are still trying to decide which Flex framework we want to use. We are reviewing several of them right now. Do you have any suggestions? We'll probably only have 2 or 3 people working on the app (which is mostly for CRUD), so we're mostly looking for a lightweight framework to help with the organization of our code more than anything.

I have read the ColdBox Proxy guide in the past, have familiarized myself with the code, and used it for Ajax calls and I think I have a pretty good handle on how it works. My questions with it at this point are really organizational questions of how I should be using it. In other words, I may know how my hammer works, but it doesn't mean I know how to build a house with it.

On your bit about juggling the two objects, that is exactly where I am at now. I don't want the duality of maintaining my model in two different places, but I can't reuse my CF model in AS and I don't want to write it all again. This is why I am wondering if my view (Flex in this case) shouldn't deal with the model. The problem with that is Flex really isn't just a view. It's a controller too and possibly another model as well. CF is really just a remote DAO at this point and I'm not sure what responsibilities should belong to whom anymore.

Antony

Great post - commenting to subscribe.

Mark Lynch

Hi Brad,

The key thing that you've already touched on is that:

  • flex is a standalone and persistent app (which is mindshift)
  • it will have it's own Model View and Controller.

What we've used with much success is a simple Cairngorm framework for the flex application (has pro's and con's, and is a bit maligned recently, but I think unfairly so). It gives good structure with very few boundaries.

You can still leverage much of you CF model in creating views - but your views become XML views which are purely for passing data into the application (or for receiving it back).

But you will definitely need a seperate model, view and controller. Suggest make that decision and keep it as simple as possible.

Have fun with it. Mark

Henry Ho

  1. sure, why not. Whatever faster. I don't see where the problem is.
  2. Maybe you should have asked your model layer (Service layer) to return the result set without objects
  3. Service Layer, I'd pick.
  4. Simple data are preferred., but it is okay to cheat, just always weight out the pros and cons and understand them.
  5. not silly at all, I think they might work, but Flex app can do more than just a html page, so it call the service directly instead of calling the MVC framework's handler.
  6. 'cause you're moving more logic to the client side with a Flex app. Therefore Flex is not just a view. You may end up with some core features implemented in both AS/MXML and CFScript/CFML.
  7. I think you can add that functionality yourself in the AS level if u like.
  8. maybe, maybe not.
  9. I'm not Hal Helms.
  10. Is okay to ramble. We all do~ :)

enigment

I'm not by any means a flex guy, and I might misunderstand your current flow, but suppose you use IBOs at a different level, as the view, rather than as part of the model.

I personally shy away from converting queries to arrays of data objects, except in the sense of a string "array" that deliver xml or json to a non-cf consumer. Seems like a lot of thrash, whose net result is to lose a lot of the efficiency and fluent coding idioms that query objects provide. IBOs as view iterators give you the ability to have custom field-level behaviors etc, while still working directly off a single native query object.

You're right that from an end-to-end perspective, having a flex front end turns the whole cf app into a data provider. In that mode, it still has a final-rendering layer, whose function is to convert the cf query into a form its customer (flex) can consume.

So say the data returned by the model is a native cf query, which the view IBO takes as input. For a native-cf front end, it loads up the passed query, and iterates over it to generate the view html. For a flex front end, it does the same thing, but instead generates xml to be consumed by flex. (Unless flex can work with cf queries natively, which I doubt, but here's where my ignorance of flex shines through; need to fix that some day...)

Make sense?

e

Brad Wood

@Mark, thanks for the comments. Thanks for mentioning Cairngorm-- choosing a good framework has been an interesting thing. I had kind of gotten the impression that Cairngorm was a little more complicated than other frameworks.

@Henry: Thanks for the categorical replies. :) Here's a couple thoughts in response.

  1. It's not that there's a problem as much as I'm testing the waters to see what other people's best practices are
  2. I thought about that, but it seems to undo all the work we did to use objects in the first place. I'm sure you can understand how it's frustrating when you think people are telling you objects are the way to go; but as soon as you run into complications someone else asks you why you didn't just use a result set in the first place.
  3. So, since I need my service layer to service both the handlers that use HTML views (returning objects) and the handlers feeding my Flex requests (Returning some simpler data type like a query), my services would need to have two versions of each method, some return type parameter to each method, or give up on returning bean objects and just revert to good-old result sets.
  4. Point taken
  5. I can't call the services directly because a) They aren't web accessible b) They require the framework to autowire them and provide the plugins they use and c) They assume the framework's security interceptor is securing their access.
  6. I think I've come to that conclusion too.
  7. True, but that would be way outside of the campy little "object generation wizard" that comes with Flex Builder.
  8. heh :)

Thanks again for the comments Henry.

@enigment: thank you as well for weighing in. The thought that an IBO is just a wrapper around a "native query object" is a little bogus. It actually hacks the query up into a struct of structs. Thing is, even though we use IBO's we pack them full of composite objects (more IBOs of course) for a pretty deep domain model. That way we can do the equiv of CompanyUser.getUser(userID=57).get("company").get("address").get("zipCode") That was three IBOs right there.

As to your question about whether Flex can "work with cf queries natively"-- It actually can with ease. The come across the wire as an ArrayList. (Think array of structs)
We've come up with a clever way to dump out the contents of our IBOs as nested arrays of structs which we have mapped on the Flex side to corresponding ActionScript classes. I'll blog about it when we're sure it's actually going to work for us.

Jim Pickering

@Brad - I realize this post was a few years ago, but I find myself in the same boat now, asking the same questions. Can you comment on what Flex framework you decided to use, if any, and how you ended up building a Flex front end for your Coldbox app, if you built it? Did you end up having to re-create your CFC objects as AS3 Data Transfer Objects (or Value Objects)? I am interested in the approach you took, and what ended up working for you; I assume your first try wasn't the best.

Thanks

Brad Wood

@Jim: I'm sorry to say that Flex project got cancelled and I never really got a chance to fully test out where we were going at the time. Our plan was to not build AS classes that matched our CF components, but to "dump" the data out of our CF objects into arrays of structs and pass it to Flex that way. That, of course, would not have included any business logic we had implemented in the CFC, it would just be the raw data. We never really got far enough to know how well that would work though.