Hope some of you got the reference…

My last post was all about the challenges I encountered getting the Cairngorm 3/Parsley insync-basic application to properly build and run. Now I have what should be a helpful model for creating new Cairngorm 3/Parsley apps.

Now finally to the fun stuff: code architecture.

There’s not a whole lot of data this program will need to deal with. It pretty much comes down to one class:

package net.flexpla.sharkys.domain
{
	[Bindable]
	[RemoteClass(alias="net.flexpla.sharkys.application.User")]
	public class User
	{
		[SyncId]
		public var id:int;

		public var balance:int;

		public var email:String;

		public var name:String;

		public var password:String;
	}
}

(Incidentally, I had to dig a bit before I found this page and discovered how all the cool kids were posting their code. One tip: switch to HTML editing before pasting your code, otherwise you lose your indenting).

So, somewhere in my program I’ll have a line like this:

	[Bindable]
	public var loggedInUser:User;

The only question now is where to put it. In Cairngorm 2, I’d just create a ModelLocator subclass and put the loggedInUser variable in there. I’d do this thinking “what a convoluted way to declare a global variable!” and “shouldn’t this be called a ModelSingleton or something?”, but I’d hold my nose and use the ModelLocator pattern because I’d be working with code built on Cairngorm 2, and the only thing worse than a bad pattern is an inconsistent use of patterns.

Cairngorm 3 stresses the use of Presentation Models, so I first figured I’d be putting it in a PM, something like LoggedInUserPM. But I cooled on this approach for several reasons:

  • The idea of separating presentation data and logic from the visual presentation is great, but that already seems to be covered under the SkinnableComponent/SparkSkin architecture.  Introducing the PM pattern seems to mean either having three classes per view, or dropping the skin. I don’t want to drop the skin.
  • The currently logged-in user doesn’t really seem to fall under “presentation data” , unless it goes in the Application’s PM. This would conflict with another Adobe suggestion, which is not to have hierarchical PMs.
  • It turns out that a client that I will most likely work with soon doesn’t use the PM architecture.

Maybe there’s some confusion on my parent, because I was thinking that “Presentation Model” was a pattern that replaced the Cairngorm 2 ModelLocator pattern. I don’t think it really does, since it’s really only ideally suited to presentation data. It doesn’t make sense to organize your application data into buckets based on where they will be displayed, particularly when some of that data may ripple throughout the entire UI.

So I need some kind of model to hold the logged in user, and I won’t be using either a PresentationModel or the Cairngorm 2’s ModelLocator. The simplest, cleanest approach seems to be what’s used in the Parsley version of Cafe Townsend: just have several models that are derived from Object and instantiated through your application’s configuration. The next question is where to locate this model within my application. Using the Cairngorm 3 recommended layering, my choices are Presentation, Application, Domain and Infrastructure. Adobe’s summary of these different layers is thin to say the least, and seems to suggest that if I want to understand them I should read the book “Domain-Driven Design” by Eric Evans. Since a picture is worth a thousand words, here’s a diagram from that book…

I’m nearly brilliant enough to make any sense of that, and since I’m a learn-by-example guy, here’s what I see in the insync application:

  • Presentation: contains presentation managers, components and skins
  • Application:  contains events, commands and controllers.
  • Domain: contains model classes.
  • Infrastructure: contains server related stuff.

I’m getting closer, but it’s still not obvious to me where the loggedInUser should go. Yes, into something like domain \ LoggedInUserModel. But isn’t there a fundamental difference between the User class and the LoggedInUserModel class? One is a data object that’s stored in a database, while the other just maintains state. Okay, I’m going nuts here. Time to move on. Here’s my structure.

  • src
    • (default package)
      • SharkysCasino.mxml
      • SharkysCasinoContext.mxml
      • SharkysCasinoTestRunner.mxml
    • net.flexpla.sharkys
      • application
        • commands
        • controllers
        • event
      • domain
        • data
          • User.as
        • state
          • LoginModel.as
      • infrastructure
        • delegates
        • services
        • vos
          • UserVO.as
      • presentation
        • components
        • skins

I feel a little sad I spent so much time thinking about all this when I could have been playing with my son or something, but hopefully I won’t have to think about this again for a long time. It’s making sense to me. And I’m glad to have considered Presentation Models and decided for several reasons not to use that pattern.

However, I would love to hear from a Cairngorm 3/DDD expert how they would structure this.

Oh, so hey, what’s up with “net.flexpla.sharkys” anyway? Thanks for asking! I just registered “flexpla.net” for the heck of it (also, scottschaferenterprises.com was just way too long), and am planning to host this “casino” at flexpla.net/sharkys.

WWCBD?

January 28, 2011

The canonical Cairngorm 3 (among other frameworks) sample application appears to be insync by Christophe Coenraets. I say “canonical” because not only does Adobe use this as their model for explaining Cairngorm 3, but it’s also checked into the opensource.adobe.com/svn repository.

But nothing’s ever simple. When I try to build insync-basic from Christophe’s blog I get this error: “The children of Halo navigators must implement INavigatorContent”. And when I try to build insync-basic from Adobe’s SVN repository, I get this error “unable to open ‘\Observer\bin\Observer.swc'”.

Ah, life with open sores!

The problem with the insync-basic from Christophe’s blog would be easier to solve, but the version checked into SVN uses more current Cairngorm libraries, so I decided to attempt to fix that instead. This project referred to three missing SWCs: “Observer.swc”, “ObserverParsley.swc” and “Integration.swc”. I downloaded the latest versions from http://sourceforge.net/adobe/cairngorm/wiki/CairngormLibraries, added “observer-1.13.swc”, “observerParsley-1.13.swc” and “integration-0.15.swc” to the project’s lib folder, edited the project’s settings and removed the missing libraries from “Build path libraries”, discovered I really needed “integrationParsley-0.15.swc” so added that, and voila! it built without errors!

Feeling pretty smug, I clicked on “InsyncBasic.mxml”, pressed F11 to debug, selected Debug as Web Application and…nothing. Nada. Zero. No browser window opened, nothing appeared in the console, nothing at all apparently happened. Of course, I try this three more times, with no more luck.

But would Charlie Brown quit? Of course not. He’s going to keep on trying to kick that football no matter what. So channeling my hero, I created a brand-new Flex Project which I optimistically called “running-insync-basic” and copied everything in. And incredibly, in my new project, InsyncBasic.mxml launched!

The last step was to get InsyncBasicTestRunner.mxml to build. There were three steps to this:

  1. Adding “-includes asmock.integration.flexunit.ASMockClassRunner” to my project’s Additional compiler arguments.
  2. In Flex Build Path \ Source Path, adding the “test” folder (which is located in the project’s root at the same level as “src”)
  3. Getting mystifying build errors, looking for more Charlie Brown pictures, removing InsyncBasicTestRunner.mxml from my project and then adding it back. Boom, problem solved.

I also had to remind myself that, no matter how an experience like this makes me feel, I’m actually a highly competent software developer.

Okay, in the hopes that this might spare someone else the misery I just went through, here’s a project that builds. I didn’t write the code, only went through the steps listed above

Download a working insync-basic here.

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.