Lately I've been struggling a bit with PureMVC and a particular application I'm building. I've been very happy with the framework up until this point (don't get me wrong, I dig it!), but the framework seems to be adding a lot of unnecessary complexity in this particular case.
I wrote a pretty useless post
about it on my blog, but Cliff suggested it would be more appropriate to open it up for discussion with the community. I agree. Please bear a couple of things in mind though: I'm not bashing PureMVC, I'm still learning the ins-and-outs of application design (who isn't!?), and I haven't made mind up on the framework quite yet. Here goes:
My project could be described as document-based: there many identical view components, each in need of mediation, but representing different models. These components can appear in many places throughout the app, nested inside of other components and containers, coming and going as the user navigates.
Perhaps, for example, we have a comment list component, but instances of that component can appear near the root of the app as well as inside Tab Navigators, Pop-up Windows, and a couple of other places simultaneously. For one thing, I found it tricky to design a mechanism for creating, registering and removing Mediators for such components as they appear and disappear.
Secondly, say the component lazily loads a list of comments from the server when it has focus: it's Mediator calls a method on a Proxy, and the Proxy sends a Notification when it's retrieved the list of comments. All Mediators of this type then receive that Notification and we have to come up with another mechanism for filtering the response - only one of them was actually interested in that particular list of comments. It's not the sort of thing that anyone else really needs to know about - the application model hasn't changed.
Maybe Proxies shouldn't be the gateway to Services, but I don't really know where else to put them in a PureMVC application.
Perhaps there are decent ways to handle the issues above, but I feel that they will probably just add code and complexity, and ultimately be fighting against how the framework was designed.
Anyhow, some other things have also started bugging me:
Boilerplate code: creating Mediators and Proxies can be quite tedious - I find my spirits drop a notch whenever I need to create one of them.. "Ok, let's do this thing! Woo! Create New Class.. Must extend some class and implement some interface.. and define my static NAME constant.. and.. ah.. create a getter to cast my view.. and.. override onRegister to hook up my view listeners.. and override listNotificationInterests.. and handleNotification.. and viola! I can start coding!" Actually, that's first time I've listed it our for myself - should keep that for next time
A Mediator could be this simple: A class with two typed properties - a reference to a view component and a reference to an event bus - both injected by an IOC container whenever the view is added to the stage. It needn't extend some framework class. We could even do away with the event bus and just use the view as a dispatcher if we were using regular Events instead of Notifications (and if we were so inclined.. I'm not).
A Proxy could be just as simple. And using an IOC container instead of a Model/Service locator (registry), we could easily reconfigure our application. Constructing, initialising and registering our actors in commands makes this difficult.
Casting: casting is to expected when using a registry to store objects, but it's not like it gives us any flexibility: we have to know the actors type (to get it's static NAME constant) to pull it from the registry anyway. I feel it's appropriate to hard-wire certain things: some things really should be concrete. What is the advantage of throwing things into a loosely coupled bucket but then having to cast them all over the place afterwards anyway?
Having only used PureMVC up until now, I have started looking into other frameworks. Each one has it's pros and cons (as expected), but each has something groovy to bring to the table.
I like: Works with Flash and Flex
I like: Mediators - keep views entirely free of framework code
I like: Proxies - are "deaf" (don't listen, but can be called directly)
I like: Commands - are stateless, and can be easily wired to system events
I like: Documentation, utilities, community
I don't like: Boilerplate code
I don't like: Framework code in my Mediators and Proxies
I don't like: Lack of formal Services concept
I don't like: Custom event bus instead of using native Flash events
I like: Combination of Injectors and ObjectBuilders can auto-wire mediators to views
I like: Binding fits naturally with framework
I like: Laura Arguello's accent
I don't like: Flex only
I don't like: Presenters instead of Mediators - making view components harder to re-use
I don't like: Bubbling events - essentially putting system communication responsibilities on views
I don't like: Declarative injection limits flexibility
I like: Works with Flash and Flex
I don't like: The word "bean"
I'm not sure about: Everything else - singleton, central event dispatcher, metadata for dependency injection, documentation
At the moment I'm feeling like PureMVC teaches the right principals (separation of concerns) but is overkill for the problems it is designed to solve. MVC is just a guide. Once you understand how the actors in PureMVC interact you should know how to treat and design components in your system without using the framework - is a generic MVC framework is even necessary? You could implement MVC without one. It might look like this:
One or more Event Busses - hold references to dispatchers and actors
Mediators - hold references to a bus and a view component
Proxies - hold references to a bus and a model
Services - hold references to a bus and a service gateway
Commands - get passed a reference to a bus when executed
IOC Container - to define rules for wiring the above components
Yes, I'm probably being very naive. I'm just battling with this stuff at the moment.. looking at my project and trying to figure out if there is a better way to build it. I'm also not sure that everything I've said makes sense - apologies if I come off sounding like a babbling lunatic! Lack of sleep and a head swimming in code
So, honestly, how are you guys/girls enjoying working with PureMVC?