These things are never done, but here’s my first cut at a Cairngorm 3 / Parsley application (view source enabled):

Some code and design ideas were borrowed from insync, others from cafe townsend.

It’s a rough cut, but not terrible. It uses Parsley model injection, commands and an event interceptor (when you try to place a bet and you’re not logged in, it prompts you to log in), Flex 4 skinning and is localizable. I added some navigation features, but think I’d need to use something like SWFAddress for deep-linking. It does not have unit testing, but I wrote it to be testable (with business logic in commands).

On my wish list:
– Deep linking through the URL.
– Using the Task Library so that after the user is successfully saved, the bet result event is sent.
– Unit testing.
– A coin flipping animation (which raises additional questions about how to synchronize events and view states)…

One way this deviates from the Cairngorm 3 guidelines is that it does not use the Presentation Model pattern. I decided against this for two reasons. First, the client I was learning this for does not use this pattern. Second, it seemed like an unnecessary layer of decoupling. If you use skins and the Presentation Model, the decoupling starts to get a bit ridiculous: for every view element you’d have a Presentation Model, a SkinnableComponent and a Skin, with the business logic contained in commands. Finally, there’s some data (such as the currently logged in user) that seems to belong in an application model rather than a presentation model – why tie it to a particular view component?

Events are separated into two categories: view events (which I prefix with “UI”) that are handled by top components, and application events which are handled by commands. For example, when the user clicks on a number to place a guess, a UIGuessANumberPickEvent is dispatched. Following the principle that only top-level components should dispatch application events, the GuessANumberPage component handles this event by dispatching the application event UserGuessANumberEvent. This is then handled by the dynamic command UserGuessANumberCommand. It’s kind of a lot of code for something so simple, but it follows a pattern, and allows for eventually testing the business logic.

There are two ways you can dispatch events so that the Parsley IOC can route them to commands. One way looks like this:

    [Event(name="guessFlipACoinWon", type="net.flexpla.sharkys.application.events.UserGuessFlipACoinEvent")]
    [Event(name="guessFlipACoinLost", type="net.flexpla.sharkys.application.events.UserGuessFlipACoinEvent")]
    [ManagedEvents("guessFlipACoinWon,guessFlipACoinLost,saveUser")]
    public class UserGuessFlipACoinCommand extends EventDispatcher
    {
        public function dispatchSave():void
       {
            dispatchEvent(new SaveUserEvent(SaveUserEvent.SAVE, updatedUser.userVO));

The other way is this:

    public class UserGuessFlipACoinCommand
    {
        [MessageDispatcher]
        public var dispatcher:Function;

        public function dispatchSave():void
       {
            dispatcher(new SaveUserEvent(SaveUserEvent.SAVE, updatedUser.userVO));

I strongly prefer the second way. It’s more readable and vastly less brittle, since metadata has no error-checking.

There’s an architectural problem with this code that seems pretty endemic to the pattern itself: the LoginModel is essentially a global that can be injected anywhere, and the currentUser setter is public. This is not nearly as bad as making the currentUser a global variable, since at least there’s only one function that can modify the currentUser, but it’s not ideal. What I’d really like to do is have the setter only accessible to LoginCommand. One possibility would be something like this:

    public class LoginModel extends EventDispatcher
    {
        private var _currentUser:User;

        // read-only bindable getter for the model's state
        [Bindable(event='currentUserChanged')]
        public function get currentUser:User():String
        {
            return _currentUser:User;
        }

        public function setCurrentUser(value:user, command:LoginCommand):void
        {
            if (_currentUser:User!= value)
            {
                _currentUser:User= value;
                dispatchEvent(new Event("currentUserChanged"));
            }
        }

The idea is that the LoginCommand could set the current user by passing ‘this’ as the second parameter. Of course, anyone could call it like so: setCurrentUser(whateverUser, new LoginCommand()), so it’s not bulletproof. Also, it might complicate testing somewhat. Still, it would make for slightly more robust code.

Feedback welcome! Thanks.

Advertisements

The StyleManager has gone through some changes in Flex 4, primarily (it appears from my very cursory poking around) to support different modules having different CSS definitions.

So that’s a nice thing. There is one subtle and obscure change, though, involving class style declarations. Let’s say you want to programmatically change the colors of all your tooltips. The following, which worked under Flex 3, does not work under Flex 4. The variable css will be null every time.

var css:CSSStyleDeclaration = styleManager.getStyleDeclaration("Tooltip");

The  fix is easy: you need to include the namespace as well.

var css:CSSStyleDeclaration = styleManager.getStyleDeclaration("mx.controls.Tooltip");

That is all.

Now that I’ve gotten my data all organized, I need to get it connected, and of course I’ll be using Dependency Injection.

Parsley offers a nice way to inject dependencies through the [Inject] metatag, but I found it tricky to get working. There’s some magic with what Parsley is doing under the hood, and one of these days I’ll try to figure it out, but for now, here’s what worked for me.

In my application file (SharkysCasino.mxml) I have:

    <fx:Declarations>
        <spicefactory:ContextBuilder id="contextBuilder">
            <spicefactory:FlexConfig type="{SharkysCasinoContext}"/>
            <spicefactory:ViewSettings autowireComponents="true"/>
        </spicefactory:ContextBuilder>
    </fx:Declarations>

In my configuration file (SharkysCasinoContext.mxml) I have:

    <fx:Declarations>
        <!-- declare the various view and model components so that Parsley can handle injection properly -->
        <spicefactory:View type="{MainView}"/>
        <spicefactory:Object type="{LoginModel}"/>
    </fx:Declarations>

And in my view class (MainView.as) I have:

        [Inject]
        [Bindable]
        public var loginModel:LoginModel;

Although you probably should write code so this isn’t an issue, loginModel appears to be null until MainView is added to the stage.

The requirements of my app are simple. It needs to be beautifully coded per Cairngorm 3 standards, it needs to support deep linking, it needs to support localization and unit testing. It does not need to be in any way useful.

What it will be is a simple online casino with two games: Guess a number from 1 to 10, and Flip a coin. The odds are stacked against you, but you get $1000 virtual dollars for free just by signing up. Nothing will be charged to any credit card, and there’s no way to actually withdraw money. It is idiotic  by design, but it should do the trick. Here’s my quick and dirty wireframe which I’ll be basing the application on:

Woo-hoo!

The next step is to translate this into a code architecture. First off, a Cairngorm 3 application has four Architectural Layers:

  • Presentation – presents data to the user and gathers input. i.e. the fancy UI
  • Application – performs the operations of the application. i.e. saving a form
  • Domain – models the business concerns of the application. i.e. the form data
  • Infrastructure – coordinates objects and integrates with other systems. i.e. talking to the server

I’ll start by mirroring the insync-basic structure and create my “sharkys_casino” project like so:

Next up, I’m going to try to figure out my classes, and see if I can’t apply this document to my design.

Applying the Presentation Model: Componentized vs. Hierarchical

But that’s enough for one night…

Design Driven Development

January 19, 2011

If there’s one step in the software development cycle that’s doesn’t get enough respect IMO, it’s the design phase. I’m not sure why that is. Perhaps it’s that programmers are expensive, and management would rather have them code than cooling their jets. Maybe it’s that specifications are hard to read and wireframe UIs are ugly and it’s hard to imagine how they’d look with nice art. Everyone’s busy. We’ll figure it out as we go…

Test driven development promises to cut development time by finding bugs earlier, but I believe it can actually generate more work if the fundamental design was wrong, as both the tests and the code being tested may now need to be rewritten.

The software development model I’ve seen work best is something like:

  1. Identify the people who will define the project (not always as easy as it sounds).
  2. Brainstorm with those people.
  3. Write up requirements: what the program will and won’t do, what platforms it will run on, et cetera. If there will be different users with different needs, identify those users and come up with scenarios for each. Return to brainstorming as necessary.
  4. Develop wireframes showing the various screens and how you get from one to the next. Prototype as much as possible. Work out as many kinks as possible before beginning to write code.
  5. Design code/data architecture and identify what frameworks and libraries you’ll be using.

And now, let the wild rumpus start!

Of course, this is no silver bullet either. You’ll get three months in and find a major new customer has become interested in the program, but they need some features to work differently. Or a new device hits the market and you have to make it work with that. Or some assumptions just turned out to be wrong. Or maybe, just maybe, you’ll find yourself ahead of schedule because you planned so well (this does happen!) and you’ll have time to implement some new features. Just spend the time to design them first.

Sort of kinda on/slightly off topic, but hilarious none the less:

Why you don’t like changes to your design

Initially, I found Cairngorm 3 a little hard to wrap my brain around. It’s not a framework per se, but a set of optional libraries, guidelines and suggestions for other frameworks to use. It almost seems possible to accidentally code a “Cairngorm 3” program, at least by Adobe’s definition. All that said, many of the optional Cairngorm 3 libraries provided by Adobe require the Parsley framework, so Adobe seems to be strongly nudging in that direction. I’m going to take the hint and build my first Cairngorm 3 application with Parsley, using those optional libraries when I can.

My goal will be to build a complete (if profoundly stupid) Cairngorm 3 application from design to completion, following all Cairngorm 3 guidelines, and including the following features:

  • Deep-linking. This application will have two pages, and each can be navigated to through a URL.
  • Localizable string resources. Because it’s the right thing to do.
  • Use of SkinnableComponent and SparkSkin for visual components.
  • Unit testing.

So what will it do? Well, a recruiter recently tried to get me to move to Austin to help build “video gaming” devices. I won’t lie – my soul is definitely for sale, but the asking price is higher than what they were offering. Still, why not build a video gaming website just for fun? Maybe not Texas Hold ‘Em, but more something like…

Creating skins in Flex 4 for existing components  such as the scrollbar (see last post) turns out to be fairly easy. Creating components that can be skinned is pretty easy as well. Here’s my take on it (View Source enabled):

Skinnable Component Example

When you drag a picture into the canvas area, a Stamp object is created, which uses a StampSkin to handle display and user interface. The Stamp class lays down the requirements it expects from the skin using the metatag [SkinPart(“true”)], and the StampSkin component handles the display and user input. It’s a nice separation between data and UI.

This was my first experiment with Flex 4, which I made in late October. It’s a little spooky, be warned. View Source enabled:
Skinned scrollbar in Flex 4
Here’s what I learned.
  1. Skinning in Spark is much, much easier than skinning in Halo. The SkinnableComponent/SparkSkin architecture is flexible and easy to grasp. Well done, Adobe!
  2. Flex is still kinda buggy. This cost me some time today…https://bugs.adobe.com/jira/browse/SDK-29160
  3. Scrolling and layout is a little tricky. Why does this Scroller contain a Group within a Group? The reason is that I want the contents of the Scroller to contain a black rectangle that’s as wide as the scrollable area, not just the visible area. The interior group is sized to fit its contents (so it extends from the leftmost textbox to the rightmost picture), causing the parent group to expand to fit its content, which then causes the black rectangle contained in the parent group to match its width.

Howdy, World!

January 18, 2011

This blog is (primary) devoted to my experiences programming in Flex 4, primarily using Cairngorm 3 and Parsley. I hope this will be useful to other programmers attempting to learn this set of development tools and libraries.