Flex Chronicles #14: Cairngorm & ARP – ViewHelper, ViewLocator, & Commands

Preface

My last Flex 1.5 project completed at the end of December utilized ARP with my change to the Controller. I worked with 1 server-side ColdFusion developer, my boss. Therefore, utilizing a customized version of a mainly Flash orientated framework wasn’t that much of a business risk. ARP has a lot in common with Cairngorm architecturally, so re-factoring it to utilize Cairngorm instead wouldn’t be that much work nor time, even if not done by someone familiar with ARP, but familiar with Cairngorm.

Why would you do this? Most Flex developers utilize the Cairngorm framework, and thus are immediately familiar with how any given Flex application is put together if it uses Cairngorm.

This new project I’m working on utilizes Cairngorm. It’s about the same in scope in terms of size, but more work is required on the client than on the server. We are mainly utilizing 1 1/2 year-old services, so there are literally no bugs on the back-end because it’s been working for so long with other services and ColdFusion components. I’m working with 1 other client developer, and 1 back-end ColdFusion developer, my boss.

Production Art

I had already spent a tad over a week working feverishly to get the main Views done. Basically, taking what the designer (art director? don’t know his title…) did in a series of Fireworks PNG files, and working the design into Flex. Production art basically, and what I’ve been doing for 7 years. I sure hope Sparkle does away with that part of my job. While there is a good feeling of accomplishment that arises from porting a design into an actual application the likes of which make Java developers drool, there is no reason I should be doing it. It is a common task, and something that sets Flex & Flash RIA’s apart from any other current implementation. It is one of their strengths, and Adobe should be capitalizing on it. Adobe dropped the ball with it back in 1998 when Macromedia’s Fireworks 2 was owning with Director 7; they were too busy showing off ImageReady’s palette features when no multimedia developer gave a flip and wanted instead to have Photoshop support 32-bit PNG’s. So let us hope with the merger, people like me can… you know, actually code and get $*** done. That’d be neat. I don’t mind screwing with margins all day to get things right and getting paid for it; it’s what web developers and I have in common. I just know me and many others could be immensely more productive if this common and old bottleneck in the production process was removed.

This week was spent integrating my Views into the being-built project. Copy folder, paste folder into another folder, and point all image embeds to another folder. Not so bad to get into a framework, eh? Well, View’s are portable, so no brainer there.

ViewHelpers

…however, the guy I’m working with, a veteran of Cairngorm, started doing something weird that I wasn’t used to. He started implementing ViewHelper’s in all of my important Views. To give some context, my co-worker borders on an OOP Purist and has had extensive experience in large production workflows. Therefore, it is not difficult for him to justify why you do certain things a certain way. We make a pretty good team because I’m the opposite; I just want the ho to compile. If OOP helps me, cool, otherwise, I got things to do.

So, rather than doing what I should and read the documentation about ViewHelpers, I had a quick debate while discussing Cairngorm with another developer not on the project. I promised myself I wouldn’t form an opinion and blog about it till the project was over, but after 2 days, I changed my mind.

I’ll write this before I go read the documentation real quick to challenge my assumptions. Basically, to me and borrowing words from my co-worker, a ViewHelper helps separate the actual code business logic of a View and the presentation of the View. One could go so far as to say MXML for GUI and AS for logic, but that’s not true. Even if you utilized an external AS file for your script tag, there are still millions of justifiable cases for using ActionScript with MXML to get the desired View to work, even with no business logic whatsoever, merely GUI related stuff. Therefore, ViewHelpers are strictly for those who are “using” the View, “those” referring to other Views or other developers. Without opening the file, reading through the code and MXML to get an idea of how it works, instead, a ViewHelper provides a set of methods that deal specifically with populating the View with data, getting data from the View, and other common operations that have nothing to do on the surface with GUI logic.

Before I call bull$h1t on that last statement, let me copy what the docs say about ViewHelpers.

Used to isolate command classes from the implementation details of a view.

In order to carry out their function, Command classes will require to both interrogate and update the view. Prior to performing any business logic, the Command class may require to fetch values that have been set on the view; following completion of any business logic, the final task often to be performed of a Command class is to update the View (user interface) with any results returned, or perhaps to switch the View entirely (to a different screen).

By encapsulating all the logic necessary for interrogating and updating a particular View into a single helper class, we remove the need for the Command classes to have any knowledge about the implementation of the View. The ViewHelper class decouples our presentation from the control of the application.

A ViewHelper belongs to a particular View in the application; when a ViewHelper is created, its id is used to register against a particular View component (such as a particular tab in a TabNavigator, or a particular screen in a ViewStack). The developer then uses the ViewLocator to locate the particular ViewHelper for interrogation or update of a particular View.

Notice my explanation is selfish, “I’m a developer, utilizing a framework that helps me. Therefore, I want to know what is in it for me.” My explanation stands by the fact that I feel ViewHelpers are for removing complexity from other developers, removing their need to actually understand how the View’s actually work. This pretty much mirrors my co-workers explanation as well, who I trust.

Do I acknowledge this as valid? Sure. When your application gets above 30 Views, at least for me, you start to get really pressed to remember what each View does, what it is named, and where it is in location to other views. For example, “Dude, what form houses that little title and list thing? Like, that’s it’s own class, right? Where is it again? In the com.company.project.view.controls folder?”

This gets worse if you spent the better part of a week doing back-end code interfacing by writing Commands and Delegates, and you return to the View’s folder to start wiring things together, and you draw a blank. This is worse when you actually open the View and have to remember how it works.

Now, add, oh, 5 other developers to the mix. That is an unacceptable load of confusion for 5 people to have for the latter problem. I can see how using ViewHelpers would allow a developer to go, “Ok, I know this View needs this data that this Command will return; apparently I just call this method from the Command… cool.”

Brainless. Suddenly, rather than spending time moving from “business logic” to “implementation details of getting that data from the server” to “shoe-horning that data amongst display logic” is cut down to 2 steps which are more related anyway; “I got the data, and throw it here.” Nice.

For extremely big projects, makes sense. ViewLocator’s, basically used to get a ViewHelper by merely using a String, make this extremely easy and portable when used in Commands.

My issues with ViewHelpers

I have serious issues with this. First off, I’ve never seen big projects succeed, so doubt it works in practice. I’m not denying they do succeed, I’ve seen them do so, it’s just I personally have never been involved in such projects. Those that do that I can see reported on blogs are by extremely talented individuals, which makes me attribute their success more to towards their developer talents vs. a framework paving the way. However, take that with a grain of salt, because almost all I have read all admit and exclaim (as much as developers exclaim, me excluded) appreciation for Cairngorm/ARP. I still just cannot see how removing know-how on how Views work empowers success.

Can you read code?

While I admit it is challenging going from a “all data, no GUI” workflow to a “all GUI, no data” workflow in the course of 20 seconds, that’s still no excuse in my opinion for a developer not to have to read code. Sure, you are more than welcome to ignore my 300 line algorithm that creates & destroys controls to make the View dynamic, but for crying out loud, you CAN read “public” and “setData”, right? All script tags are up top in MXML to make the MXML component a class, and thus are in a predictable place. Granted, with ActionScript classes, things are not always so predictable location wise, but if a developer does what she/he is supposed to do, and repeats the same style throughout, then there should be no issue finding the public functions, right?

…am I suggesting to learn the style of 30 developers? Hell no, you should be following an at least mildly mentioned development standard such as “all public functions go at the bottom of a class” or “all of our View’s use this Interface for setting data” or something to that effect.

The Command who knew too much

Next, the fact Commands know anything at all about View’s, even if it’s through a ViewHelper, still feels wrong to me. Commands are touted as portable, and yet here they are taking data to a specific View; using a ViewHelper as a go-between does not illustrate encapsulation to me in the slightest. It’s a feint and I’m not taking the bait.

When I first learned about using Commands in ARP, suddenly my _root timeline in Flash (or my Application.mxml code in Flex) was reduced form thousands of lines of code to 500 or less. That’s a pretty bad ass concept! That exuberance, however, led to me treating Commands as a “sliced up and organized Controller code chunks”, which actually makes them too smart. My co-worker told me that Commands are really actions the user can take in using the application, and I agree; “SaveUser”, “DeleteSomeItem”, etc. Therefore, tying commands that have flexible usage to a specific View removes their inherent flexibility.

I’ll admit I still haven’t figured out the best way to spew out data that the Commands get. For simple ones, it’s easy to call the result function that the Controller specifies, and go true or false, “Yeah man, it saved.” or “No dude, it didn’t save.”. Even XML.onLoad does that pretty well, and no one has issues; it is very straightforward.

But at least I’m leaving that up to the Controller to handle since he is the one who is supposed to dictate which View gets what data if it isn’t already bound to it.

This is something both ARP and Cairngorm both do that I don’t like; giving too much power to Commands over Views. This is because I view Commands as chunks of executable code that are liaisons to the back-end, not field officers with delegated authority over parts of my visible application.

Project Scope – The Pragmatic Contention

Finally, and this is merely pragmatic: most projects I do are 2 to 5 developers, not 30 developers. I’d argue you give me a bad ass Java developer, 2 other client developers with a good attitude, and a competent manager who will stand her/his ground against scope creep, and we can produce some serious amount of work that actually works.

ViewLocators

ViewLocators? Ok, I’ll somewhat concede ground on this guy. I’ve had 2 projects in my entire career where I HAD to have the Controller know about a deeply nested View. While event bubbling discussed by Ralph and I, solves the need for a deeply nested View to inform high command about some action, having high command rely instructions to that deeply nested view was a bitch; complete pain in the ass consisting of using a bucket-bridge technique of defining proxy functions. Meaning, the main View defines a function for the clear and explicit purpose of passing the function call down the chain to it’s nested View, who in turn does the same function definition, until you finally arrive at the View who houses your target View, and relay’s the command.

Stupid, and only justified by deadlines. A ViewLocator on the other hand handles this eloquently by using a string to get access to a ViewHelper by name, and calling the method. Nice.

…too bad I still dislike ViewHelpers, but I still don’t deny the ViewLocator’s validity.

Command Creation Differences in ARP & Cairngorm

On a side-note, one thing I noticed differently about ARP & Cairngorm is that ARP creates Command classes on the fly; meaning, when the command is executed, the Command class has an instance created. In Cairngorm, Command class instances are created at the beginning of your application’s startup, and they thus remain in the FrontController’s hash array (a.k.a. associative array, a.k.a. Object). I’ve been going back and forth on this, and I still don’t know which has the better implementation. No one not-working for Adobe’s Flash Player team (cept for 1 dude, and his entry was wiped from the face of Google) knows how the Flash Player Garbage Collection works for Flash Player 7. Flash Player 8 is a little documented via Tinic Uro; he even wrote an example of where creating 1 member variable is better than creating many local variables that use optimized registers merely because it’s easier for the Flash 8 garbage collector to remove them (can’t find the link). Bottom line, you only ever actually run 1 Command anyway in Cairngorm, so creating them all at startup, and just keeping 1 instance around is great from a GC perspective. However, this removes the ability for Commands to retain knowledge via member variables on a case by case basis if there is only ever 1 instance. Hell, even Event objects in Flash Player 8.5 have member variables. So, while Cairngorm is apparently more GC friendly as best we can guess, ARP lends more flexibility in Command usage.

Both ARP and Cairngorm do the “event triggers command” thing that I hate. By dispatching an event, this magically triggers a Command that you map at authortime in the Controller class.

Conclusions

In conclusion, I couldn’t live without ARP or Cairngorm. Not having a framework to develop small to large applications is a fate worse than death and I’m glad they were created; they empower me to be successful. As much as I bitch about the concepts, you don’t see me creating my own framework; I instead still continue to use and promote theirs! I just want them to be better, is all, and some of my challenges are merely so I can learn more about them and their implementation in projects through discourse.

9 Replies to “Flex Chronicles #14: Cairngorm & ARP – ViewHelper, ViewLocator, & Commands”

  1. maybe i’m not following with the whole idea of view helpers correctly, but wouldn’t their usefulness be diminshed with the idea of having a view subscribe to a model that broadcast change events, and avoiding having the commands query or call methods on a view directly (which looks like the way ARP is moving in it’s next version)?

  2. Sort of. View’s bind to a ModelLocator. A ModelLocator is updated by a Command or Business Delegate. At that point, yeah, no reason to have a ViewHelper.

  3. Jesse; let me be clear here, that we’ve been advocating for a LONG time now the use of the ModelLocator (a phrase that we coined on the Cairngorm team because of the symmetry with ServiceLocator and ViewLocator).

    We’ve been advocating the ModelLocator pattern as ‘flashape’ mentions above, for a good 9-12 months now, and the sample apps that we ship with Cairngorm show this practice in anger.

    Commands should update the model in the ModelLocator, the views should subscribe through data-binding to the ModelLocator, and the use of view helpers should only be in ther *very* limited cases where the model needs to be manipulated in some way before it is rendered by the view.

    Clearly the legacy of Cairngorm is confusing for people who aren’t reviewing the sample apps; this will be rectified shortly with some updated articles I hope to have available soon, that clarify current best-practice as we see it.

    But let me reiterate the most important point here — the ModelLocator pattern that we introduced several months ago is absolutely the best-practice that we have been advocating and using for quite some time now. It’s usefulness is validated by it’s inclusion in the ARP pattern catalogue as well, which does a little more heavy-lifting for the Flash developer who doesn’t have access to Flex data-binding. Since we’re focussed firmly on Flex-based RIA development, our ModelLocator implementation is simpler for our typical use-case.

    We introduced the ModelLocator when we realised that people were just overabusing it, to complicate designs. And many of the very fair points you make above, were the reasons that drove us to drive others towards a ModelLocator as well.

    Did I say to remove all your ViewHelper code and use ModelLocators if possible ? Good. :-)

  4. My second last paragraph in above post doesn’t make sense ! Meant to say ‘we introduced ModelLocator when we realised that people were overabusing ViewHelpers (by creating too many of them, and ‘pushing’ data onto the view rather than binding to the view).

  5. Steven, thanks for the clarifications. I’ve only found one use case that confirms the above about changing data. That’s 1 in 60 Views, equaling 1 need for a ViewHelper out of 59 that don’t, and work just find with binding as described above. It makes me feel better to know this is the preferred way to develop in Cairngorm.

  6. Hi Jesse,

    i’m neither using Caingrom, nor Arp on an everyday base, but to me the split between View and ViewHelper is very useful. I like to keep my views as dump as possible. All they contain is setter/getters for the data to display and maybe they emit some events, if it is an interactive view, but nothing more. If i want to test this view, i don’t need the whole framework to work, but just a little dummy class, which calls the setters with some fake data. On the other hand, if i need to test the rest of the application, i can simply replace the view with a dummy, which does automatically, whatever i want to test.

    So what the helper basically does, is separating two subsystems.

    Cheers,
    Ralf.

  7. One of the inherent and very obvious differences in Flex and Flash is the clear separation of presentation from biz logic (MXML and AS), so the ability to update / interrogate a view in Flex with a ViewHelper, an additional class that further facilitates the decoupling of pres and biz logic, totally works for me. In addition, I liked the fact that my view was nothing more than a *dumb* view

  8. Thanks Riley and thanks for sharing your experiences!

    To me, the Commands in Cairngorm have context based on how they are supposed to run based on the event it gets in the execute function. This event has the data you passed it from the event. So, technically, it is a roundabout way of doing my change to ARP of CommandRegistry; allowing the Application more control over the context in which a command runs. So, yes, Aral even suggested I relax, and use handleEvent since I can intercept any event, and handle as I please. In ARP, that felt too limiting, hence my need for a Command to have a result handler to call vs. having it update data itself, or use a ViewHelper. Instead, I wanted to let the Application handle context. This leads in nicely to chaining commands. I’m aware Cairngorm already has this, but I dig all of that happening in the Application.

    In Cairngorm, I’m still getting used to ‘Hey command, here’s your context in which to run based on the data I passed in as the 2nd parameter to the event.’ Does it work by design? Sure. I guess I just feel uncomfortable passing arbritary/vanilla objects that they themselves have context. For example, ActionScript 3 encourages the events be actual classes that extend flash.display.Event. This allows great context to the restult handlers who handle the events since the events have strict-typing on the data they have, and there is no misunderstanding on the context of the event. If there is, you get a runtime exception.

    However, in retrospect, it’s totally cool. We have a somewhat strictly typed language that’s easily hacked around, and Cairngorm is at version 1, Flex at 1.5. So, again, I retierate I love ’em (the frameworks), and can’t live without them. I just think there is tons of room for improvement which ActionScript 3 will help with a lot. From a theory perspective, the ViewHelper vs. View -> bind to ModelLocator is already promoted. It all comes back to how people think Controller code should be written which is a varied topic.

  9. Jesse:

    …since this post was started in the Flex / Cairngorm vein, and I don’t even want to start to ignite the MVC discussion, I’ll go with yup, it does ‘it all comes back to how people think Controller code should be written.’ ;-)

    ..and yes, I also totally agree with this:

    ‘modified Commands to have a resultFunction; much like a Delegate, Commands can now call a function in a specific, pre-assigned scope when completed rather than some implied known function on viewRef.’

    as I did the same thing. I find myself almost always adding in scope and callbacks (both result and status) to objects that perform services and what not.

    [slightly OT]…in fact, speaking of services, I did exactly that for my XMLService object. I found that many clients have been / continue to leverage XML as their data vehicle — even more so now with all the new XML APIs — so I created a an XMLService object that’s modeled after the remoting API for ARP — returns a Result or Fault object. I then added a CSSService and LoadVarsService object as well. Mind you, I did this for ARP and haven’t decided if necessary or warranted in Cairngorm.

    …sorry, I realize this was slightly off-topic, but I’ve also been engulfed with the new additions to ARP 3 that Aral’s suggesting, and thus, I’ve been just waiting to dive into the future framework as well as hear what everyone thinks…to that, it’d be interesting to know if Aral’s planning on an AS2 and AS3 vr of ARP3…

    I’ll end with, runtime type checking…good schtuff.

Comments are closed.