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.