Here's my personal rule of thumb:
If the view is so complex that all the view components can't comfortably reside in the same folder, then it's probably time for MultiCore.
In which case, the folder structure will end up being something like this:
com.me.myapp.common.model.* // Shared VOs, Proxies, etc
com.me.myapp.common.view.* // Shared View components, embedded assets,
com.me.myapp.common.controller.* // Shared constants, etc
com.me.myapp.shell.model.*
com.me.myapp.shell.view.*
com.me.myapp.shell.controller.*
com.me.myapp.modules.subsystem1.model.*
com.me.myapp.modules.subsystem1.view.*
com.me.myapp.modules.subsystem1.controller.*
.
.
.
And once again you find yourself with simpler subsystems, more room to breath in each core's view/components folder, and most importantly, the ability to reuse those entire modules elsewhere. Or to swap them out easily with alternative versions. Or to outsource them easily. All that goodness that modularity brings.
But
you're thinking:
Wait, I'm building a car I don't want to have to build complicated communications plumbing and or special interfaces just to bolt the wheel subsystem onto the chassis subsystem.Once you investigate MultiCore,
it is easy to get the idea that you have to create special interfaces or message protocols to get modules to work with each other. And while if you want two modules to carry on meaningful but anonymous bi-directional communications with each other in the PureMVC realm, this is what's advocated.
After looking into Modules in Flex, say, you think, ah,
I've got to load the module and be concerned with it's lifecycle to integrate it into my program. Plus, in order to do it right,
I'll need to create separate projects for the app, the modules and the common libraries they all share. Sheesh! Is switching to MultiCore really worth all that work?The answer is: on a really large project where lots of people will be contributing and the maintenance legacy will go on for years,
yes, absolutely.
The pain of setting it all up will be more than compensated for by years of predictable maintenance in an environment that expands easily and whose fractal-like subsystem design makes management of enormous systems simple.
But if you simply have a big app that a handful of people will be busting out and are against a short deadline, then all that overhead will sound ludicrous to you. As Joel Spoelsky recently noted in his blog:
Shipping is a feature. A really important feature. Your product must have it. (
http://www.joelonsoftware.com/items/2009/09/23.html)
There is another possibility which has proven a viable path if you're using Flex/AIR
1 and plan to stay there. It lets you use MultiCore and organize your applications according to the predictable package structure described above, while still making it to the deadline just as fast as if you just started subdividing your view/components folder.
Create and use the Modules as a regular View Components.You can essentially treat an mx:Module like you would an mx:Canvas; extend it and make a custom component to be plugged into your app's view hierarchy somewhere with a simple MXML declaration.
But sock it away in its own package space in the project (com.me.myapp.modules.subsystem1.*). Give it its own Facade with it own startup apparatus, its own Proxies and Mediators and View Components. Then simply instantiate the mx:Module subclass in your code just as you would a complex view component.
The advantage is you can encapsulate its PureMVC management inside its own core. The Shell doesn't need to poke pipes into it and send it messages or call interface methods on it - it's no different than a DataGrid to be used inside the main app! You can have it communicate with its parent by sending events.
And the nice thing about this approach is that
you can ship on time, but be perfectly set to refactor the modules into separate projects or build special plumbing and module loading and management
in the future as needed.
-=Cliff>
PS: Don't consider MultiCore 'way over your head'. It's the same as the Standard version except that it enables modularity. The only differences are essentially the import statements, the Facade getInstance method (takes an id for the core). So starting with MultiCore ensures you never have to migrate to it later if you decide to bust your app up into modules.
1You can build cores using Flash as well, they just don't implement mx:Module of course.