Discovering PureMVC, and scaling the learning curve
Background
A while back I began work on a personal project which would involve me finally getting to grips with Flex, Django and XML-RPC. I’ve been using Actionscript 3.0 for quite a while, but my experience with Flex had been relatively minimal. After getting past the initial “What the hell actually is Flex?” thing I spent some time trying to learn the basics.
I started off by going through the Flex Builder tutorials, built the sample application featured in Flex 3 – Training from the Source , signed up for the Flexcoders mailing list and even built a couple of little apps to help me automate some fairly dull database maintenance I’d been putting off. But at that point I’d never done any real work with Flex, and it quickly became obvious that I wasn’t sure where to begin when it came to structuring a fairly large application.
I’d read a bit about the various frameworks available for Flash and Flex, but I’d always kind of written them off as not applicable for me. I had my own way of doing things which, up until now, had always worked well for me and I saw no reason to change. This time, things were a little different, and I decided that it might be time to revisit them.
Cairngorm
First off, I looked at the Cairngorm framework. I found a link to David Tucker’s excellent video tutorials, which begin here, and initially I was really keen on what I saw. The widespread adoption of this framework was a big plus for me – I found a whole load of excellent Cairngorm resources online, and I realised that understanding this framework could turn out to be very useful for future projects.
However, because of the nature of my project, I’d already decided that I’d be using Modules to break up my large app into smaller, easier to manage chunks. In theory, I’d be able to re-use some of these modules in other projects if I wanted (although sometimes I wonder how long I’ve spent making code re-usable only to never, ever, re-use it). Anyway, Cairngorm uses Singletons in various places to control access to among other things, its Model, and as a result I couldn’t find a way to successfully use multiple instances of Cairngorm within one running application, which made it unsuitable for my Module-based project.
PureMVC
After much cursing, weeping, and a little violence, it was back to the drawing board. At this point, I started reading up on PureMVC. OK, so PureMVC was another framework for Flash and Flex, but not only that, it was not Actionscript-specific, and was being ported to other languages too. Just as I’m unlikely to find myself reusing most of the code that I’ve obsessively tried to keep generic, I’m also unlikely to need to build a huge application using ColdFusion, but it’s still strangely appealing to know that if I did, I might have a good idea where to start.
Now you mention it, maybe I should start learning ColdFusion? Oh look, they’ve ported the framework to C# too, should I try to learn that before or after ColdFusion? Argh! This is getting out of control…
Anyway, PureMVC also uses Singletons heavily to provide access to its core actors. However, based on feedback from the user community, development had begun on a “Multicore” version of the framework, initially designed for AS3.0. It was currently in Beta, but seemed fairly stable so I decided to give it a try.
(Note: recently, the Multicore version is out of beta, and the consensus seems to be that there is now no point in using the Singlecore variety, even if your application only requires one instance of the PureMVC framework).
The Multicore version works by replacing the Singletons described above with “Multitons”. From Wikipedia, “The Multiton pattern expands on the Singleton concept to manage a map of named instances as key/value pairs”. What this means is that your application can employ as many different PureMVC instances as it needs, each one using its own unique key to control access. All of this functionality is nicely hidden away within the framework, and the syntax for using the Multicore version is practically identical to the Singlecore version. There are a few slight differences, which I will try to pick up on in a separate post.
So – by using this version of the framework, my application’s modules can all use their own instances of the framework without conflicting with each other at all. Nice! Now how the hell do I use it?
Getting to grips with PureMVC
Initially, I thought the learning curve would be fairly steep. The PureMVC implementation of, er, MVC was very different from my own, which I’d been using happily for a number of years. It called things by different names, (Facade? Mediator? What??), and I must say that at first glance it all seemed a bit complicated. I was worried that for every little piece of interactivity in my application I would end up needing to create 3 or 4 classes, and that it would take forever to build even a simple interface. By now, I was sick of reading, and so it was time to blindly dive straight in.
Initially, it did feel like a bit of a pain to have to decouple everything so strictly. I found myself creating a lot of classes to do some pretty simple stuff, and it felt like there was a fair bit of repetition going on. However, slowly I started to realise that when I was writing new code, more often than not it would actually “work first time”. I dunno about you, but that’s a pretty rare phenomenon for me – normally I would expect at least one annoyingly hard-to-track-down mistake littered somewhere to keep me on my toes.
A few times I was a little confused about how best to structure what I was trying to do in a PureMVC way, but each time a quick trip to the Discussion Forum proved invaluable. After a while, these moments of confusion had passed and I found myself “thinking in PureMVC”. Behind the scary looking diagrams, and odd-sounding names for things, the framework is actually pretty simple and now that it’s starting to click for me, it’s definitely improving the speed of my development. Sure, there are still things that make me want to gouge out one or both of my eyes (for some reason, I find overriding the listNotificationInterests method in each Mediator particularly soul destroying – this isn’t a complaint aimed at the framework, I just hate typing), but overall I’m a happy chap. Is it right for every project? I don’t know. But it’s definitely working well for what I’m currently using it for. Christ, I’ve already re-used some code. Woo!
Here are a few of the struggles I’ve had with when trying to get to grips with the framework:
- My own stubbornness
I was a bit set in my ways – I had my own way of doing things, and my own names for things. I struggled to understand the framework initially because I was trying to apply, or convert, what I was reading into my own techniques. Once I stopped doing that, and just accepted that PureMVC worked in a different way, things started to become a lot clearer. - Understanding the different actors in the PureMVC pattern
As I mentioned before, I found the names for things in the PureMVC a little confusing. In my implementation of MVC, I had Models, Views and Controllers. The Facades, Proxies, Mediators and Notifications created by PureMVC were extremely confusing to me at first. It sounded extremely confusing, and nearly put me off. The best suggestion I can make is to read, and re-read, the Best Practices document. This is the best single piece of documentation that I’ve found on PureMVC, and it was after reading this document from start to finish a couple of times that I really started to understand what’s going on. - Knowing where best to define Constants (for example, Notification names)
I’m still not sure about this one. Currently, I’m tending to define the Notification name in the class which sends out that Notification. This worked well for a while, but I’ve had a couple of instances where multiple classes send out the same Notification, which then gets a bit confusing. I’m a bit reluctant to define them all in the ApplicationFacade class, as otherwise that class is gonna get pretty long and ugly. The other alternative I can think of would be just to create a class which serves no purpose other than to define the constants. That way, they’re all in one place. How are you solving this problem?
(Update: I’ve recently switched my approach here and I’m now storing all notification name constants in a single class which any other class can just import if it needs. This approach is working well for me, and feels like less of a hack, but I’m still wondering if there’s a better approach which I’ve not thought of yet.)
As an aside, I recently had a farcical experience which resulted in me losing a hefty chunk of work from the project. I accidently deleted my SVN working copy for one of my modules, and somehow when I was attempting to check-out the code again I managed to remove the entire repository. After much wailing, faffing, and fiddling, I decided that it was gone for good.
The actual code that was lost was the first work I’d ever done in PureMVC, and from my records it was over 20 hours of work. When the tears had dried, I sat down to start writing the code again, from scratch. This time around, it took just over 2 hours to completely rebuild the code. Not only that, but I had a much more flexible system at the end of it. I’d originally written this code about a month ago, and I’m pretty pleased that after just a few short weeks (of very part-time experience with PureMVC) I’d been able to build the module that much quicker. I’m hoping the framework is gonna help me build a well structured application, and once the last few areas of confusion I have about ‘best-practice’ are ironed out, I’m hoping the whole process is going to be fairly smooth.
If you’re about to look at the various frameworks available for the Flash platform, I can (so far) heartily recommend PureMVC. Ignore how confusing those big scary diagrams look at first, what’s going on underneath is surprisingly simple. Good luck!