Adobe DevNet publishes my blueprint for Flex apps

December 29, 2006 on 7:20 pm | In Flex, Programming |

Wow! I’ve been so busy that I actually forgot to blog about something nice that happened: Adobe has published an article by me, outlining a general architectural blueprint for Flex applications that adapts MVC-style patterns in a nice way. The article is available at
An architectural blueprint for Flex applications on adobe.com.

This article is based largely on a talk I presented at MAX 2006 on this approach. Writing it required that I reduce a lot of partly-improvised speaking (and some useful semi-animated interaction diagrams) into cold hard words on a page and static illustrations. On the flip side, I could be much more explicit with code samples, and take the time to explain some things more clearly.

The prop for all this explanation remains my ReviewTube mashup application. There’s been a lot of activity on that app lately, which is gratifying.

17 Comments »

RSS feed for comments on this post. TrackBack URI

  1. Thank you so much for your article. If only I had discovered it earlier, it certainly would have saved me days and days of work.

    Thank you,

    Maz

    Comment by Mathieu LEMAIRE — January 13, 2007 #

  2. Great, great article and to me makes more sense than using Cairngorm which I’m getting into more and more. I was wondering if you had additional examples or any other small apps built off of the architecture you’ve established. I would love to build an application based on what you’ve started but only have this example and might have to stick with Cairngorm because of documentation. Anyway great article and thanks!

    Comment by Paul Rangel — February 11, 2007 #

  3. First, thank you very much for your article. I’m finding it easier to wrap my brain around your approach than Cairngorm, so I’ll probably use your structure as a model for my own Flex app.

    I’ve imported ReviewTube into a new project, and switched to your “mock” controller. But when I try to compile the project I get this error:

    “1046: Type was not found or was not a compile-time constant: MockReviewTubeComponents.”

    If I comment out the offending line (in ReviewTube.mxml) I then get the following error:

    “Could not resolve to a component implementation.”

    Clearly some sort of namespace issue, but I can’t figure it out.

    Any help would be much appreciated.

    -Barton

    Comment by Barton Listick — February 21, 2007 #

  4. Barton, I’m not really sure what the problem is. Usually the “could not resolve” error is what you get when you refer to a class or a component that can’t be found. You’d have to tell me the exact line number in order for me to be of help, but it’s probably something very simple.

    If the system cannot find MockReviewTubeComponents, then the MockReviewTubeComponents.mxml file isn’t where it’s expected to be according to the package. Make sure it is there, next to ReviewTubeComponents.

    I just demonstrated the mock components at a talk recently and I don’t believe that component broken.

    Comment by joe — February 22, 2007 #

  5. Great article. Probably the most down-to-earth explaination of MVCS I’ve seen. I’m curious why you chose to use HTTPService classes instead of WebService classes for communication, and how you might have structured things differently had you chosen WebServices. Also, I was curious about your decision to put the XmlHttpOperation class in with your Controller classes - isn’t that a Service class?

    Thanks again for a terrific article.

    Comment by Tom Lee — February 27, 2007 #

  6. One other question - I’ve been wondering about the merits of implementing the Model as XML, instead of value objects. XML would seem to have a few advantages:

    1) It would be easier to serialize the model and save it in a local shared object for later restoration
    2) It would be easier to store revisions of the model for undo/redo purposes
    3) It would be easier for the view to databind to it

    I guess one potential downside is that it would be difficult to strongly type objects stored in this manner. I’d love to hear your thoughts on the matter.

    Comment by Tom Lee — February 27, 2007 #

  7. I’ll try to answer your questions, Tom.

    1. In this particular example I used HttpService because WebService must use SOAP/XML, rather than the freer XML schemas used in the ReviewTube server application. I wanted to show that XML parsing can be associated with services in a way that is more structured and type-safe than the typical examples one sees with HTTPService. More generally, I find WebService kind of unwieldy and slow, plus it does not handle SOAP errors well. At Allurent we have written our own SOAP handler to replace it.

    2. XmlHttpOperation shouldn’t really be in the controller package. None of the operation-related classes should be there. In production code we have a separate “operation” package.

    3. I don’t think it is a choice: either XML or value objects. You can have the best of both, using value objects where you’re writing code and XML where you need a serialized stream or a document. One can freely convert between them, or build a “synchronized” model that uses strongly typed value-object wrappers around E4X underneath, maintaining both simultaneously. I’m giving a talk at 360Flex next week about how to generate both value-object classes and serializers from a “master” data model description, itself in XML.

    I strongly prefer value objects as a type-safe model layer for application programming that is binding-friendly. It’s just too easy to make typos, and binding and E4X don’t get along so well.

    When it comes to undo/redo purposes, I agree that XML is easier to implement. Again, though, it’s not an either/or choice. In one Allurent application that uses the XML-wrapper approach, edits to the strongly typed wrappers generate undo/redo commands at the XML level. Easy!

    And one can generate undoable commands from a master XML model (hmmm, maybe I’ll include that in the talk).

    …j

    Comment by joe — February 27, 2007 #

  8. We started using your MVCS architecture to build an application using RemoteObject instead of HTTPService. We’ve been able to return data from the operation successfully, but we don’t see how our data model is bound back to the view. We see in your example where you return the empty dataProvider to a view (Controller->getRecentVideos()), but we don’t see how the model and view are bound together (Controller->loadReviewComments()). Hopefully that makes sense! Thanks in advance, and killer article.

    Comment by kevin — March 6, 2007 #

  9. Kevin, the idea is that the view calls the Controller, say, getRecentVideos(), and immediately makes use of the returned empty model, either binding to its Bindable properties or (if it’s a collection) using it as a dataProvider to some component. Either way, the result is that the view is now listening to change events coming off that data model, which will eventually occur once the data comes back.

    If you download the ReviewTube source and check out the details, I think it’ll be reasonably clear.

    Comment by joe — March 7, 2007 #

  10. I’ve been working through the process of architecting an application based on MVCS, and I thought I’d share some thoughts I had along the way. Forgive me if I get a bit long-winded, and please let me know if it sounds like I’m misunderstanding something fundamental.

    First, I found it useful to create a set of Parameter objects to be passed into the Operations - this way, each parameter is strongly typed, and it is this parameter object which is passed through the Service object, into the Operation (simplifying the method signatures). The Parameter objects all inherit from the same base class, which has a toSimpleObject method which returns an object containing name/value pairs (HTTPService requires a simple object - strongly typed objects won’t work). In my case, each web service call required around 10 parameters, so changes in the web services became more difficult to manage. If the parameters of a web service changed, I had to update them in the service interface, the service object, and the operation object. With a Parameter object, the changes are in one location only. Now to decide where to put the darn things - do they belong in the Services packages, the Operations package, or are they more properly part of the Model?

    Secondly, I’m thinking a “ViewState” object would be a useful addition to the architecture. It would store any view object’s properties that you might wish to save for later restoration, but that don’t really belong in the model. For example, you might have a preferences PopUp dialog with some comboboxes whose selected indexes you’d like to persist each time the PopUp is shown. For some reason it doesn’t feel right to put those kinds of things in the Model, but maybe that’s exactly where they belong…? Care to comment?

    Thanks a lot for your article. It has taken me a giant step forward!

    Comment by Tom Lee — May 23, 2007 #

  11. Tom,

    Thanks for the great comments.

    (I also took a look at your blog and responded to a much earlier comment you made about the question of why there isn’t a unitary Model object somewhere. Briefly, the answer is — there certainly can be such an object and in many cases it’s a good idea, but for the particular case of ReviewTube it doesn’t seem to make sense to me.)

    1/ About the Parameter objects, I assume those are internal to the Service/Operation part of the architecture and don’t make it into the Service interface that the rest of the app calls. If they are indeed internal, then it sounds like a fine solution to your problem — presumably you have various stock parameters for your HTTP requests and this gives you a way to encapsulate their structure. If they are exposed as a public data type, then the app developer has to pass a FooBarParameter object into each Service method, which seems like a big nuisance if the parameter is just a String, an int, or whatever.

    2/ Questions about ViewStates and things like them come up a lot because they fall into a gray area. When is a ViewState a separate model-like object and not just some property of some view somewhere? My feeling is that a persistent ViewState is a perfectly legitimate *kind* of model, but not the same model-with-a-capital-M that represents the semantic data for the application. The fact that it gets persisted is a very good argument for separating it from the actual view components themselves. I certainly would want to keep ViewStates in a separate object, possibly living in the Controller (since the controller presumably plays some role in applying these states to the view).

    Hope this helps!

    Comment by joe — May 23, 2007 #

  12. Joe,
    Thanks for your response. Actually, my Parameter objects are public - I think I need to explain them a little more fully. The reason these Parameter objects came about is that the web service calls are so verbose: each requires around 10 parameters, many of which are the same (username, password, security token, etc). I found myself typing the same argument lists over and over again (in the service, service interface, and operation objects). As I said before, each Parameter object inherits from a base class. What I failed to mention before is that this base class contains the ’stock’ parameters and initializes them with data from the Model. So, for example:

    public class OperationParams{
    private var username:String = Config.instance.currentSession.currentUser.Username;

    // Username
    public function get Username():String{
    return this.username;
    }

    public function set Username(v:String):void{
    this.username = v;
    }
    }

    (I’m using getter/setters because they can be overridden by a subclass if need be.) This way, any time a Parameter object is instantiated, it is automatically prepopulated with those common values. The Parameter object is actually instantiated in the Controller, populated with the remaining (non-common) values, and passed into the Service method (which passes it into the operation it returns).

    This doesn’t feel right because I came up with it myself, as opposed to implementing a known good interaction pattern. Is there something I’m misunderstanding in your MVCS architecture that would make the need for Parameter objects irrelevant? Or is there another interaction pattern that you feel would better serve the purpose?

    Thanks again for your indulgence.

    Comment by Tom Lee — May 23, 2007 #

  13. Joe, I’ve really enjoyed working with ReviewTube and trying to get my arms around MVCS. However, I have struggled with one thing: I’m trying to break the UI into different “windows” and it’s proven harder than I suspect it should be. For example, I split the MainView.mxml into two separate MXML components - one w/ VideoCommentary and one with VideoBrowser. The result is VideoCommentary does not “see” a selected video and I really cannot figure out why.

    Can you help??

    (For reference, I am trying to put ReviewTube components into MDI windows like those used by Christophe Coenraets.)

    Comment by Mark — May 24, 2007 #

  14. Tom: more on the Parameter question — I don’t think a pattern is *ever* bad merely because one came up with it oneself, providing that it’s easy to understand and easy to justify and document.

    What I find here (now that you explained it in more detail) is that you have simply factored out some objects: strongly related sets of values that make sense to package up and send to the server as a single object. I think of these as Model objects of a sort. They are not all that different from model objects that travel in the other direction, sent from the client to the server.

    So there’s nothing especially exotic going on here, other than the fact that you call these factored-out objects “parameters” and make them 1-to-1 with the set of operations. Such refactoring is a natural way to simplify any complex API with recurring subsets of parameters. I think if you focus on just rolling up the values that always occur together into named classes, rather than always having a single XYZParameters subclass for each XYZOperation, you’ll have a more natural and intuitive Service interface. At that point, one might name than “XYZInfo” objects or something of that nature.

    Comment by joe — May 24, 2007 #

  15. Mark — without seeing your source code, it’s hard to say why this doesn’t work, but there’s nothing in the architecture that would rule it out. It’s probably some minor problem with how your bindings are set up. As long as VideoCommentary’s ‘video’ property gets set to a Video, it should work since it has no idea where that object comes from.

    Comment by joe — May 24, 2007 #

  16. Joe, thanks for the response. I hope you don’t mind a follow-up. I think I am confused by the Session.as: it dispatches a “selectedVideoChange” event which does not seem to have any listeners. Meanwhile, yes, I believe the Bindings are amiss somewhere which begs another question: Any recommended techniques for debugging them? The problem I often have is that when a binding is set is different than when you expect to see results from it so it can be hard to debug any problems.

    Comment by Mark — May 24, 2007 #

  17. Joe, thanks - your idea about grouping like parameters together rather than having a 1-to-1 relationship between Operations and Parameters makes a great deal of sense. I think it’ll be easier to understand in the long run. Thanks again for the tips, and keep writing - this blog is one of the best Flex blogs going, in my book.

    Comment by Tom Lee — May 25, 2007 #

Leave a comment

XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>

Entries and comments feeds. Valid XHTML and CSS.
All content copyright (c) 2006-2007 Joseph Berkovitz. All Rights Reserved.