- PureMVC’s functionality centres on two design patterns that have fallen out of favour of late: Singleton and Service Locator. Both patterns make unit testing harder than it need be. Both are glorified global variables and thus are difficult to mock and tend to persist state between tests. The use of these patterns is also a barrier to using it with that “flavour of the month” pattern: inversion of control (IoC). IoC relies on objects being told their operating environment, rather than asking it of a globally accessible system, such as a service locator.
- PureMVC’s cross-platform support is also its Achilles’ heel. Much of it is written in a very language agnostic fashion, eg as Java doesn’t have properties, they aren’t used in versions for languages, such as AS3, that do support them.
With more modern MVC solutions, such as – in my opinion, the “best of breed” – Robotlegs, becoming available, PureMVC has probably had its day for many people. However, this is more true for new projects than for legacy ones. If you have a large PureMVC-based application, converting it to Robotlegs is far from trivial, and it is questionable whether the investment in time is worth it. To my mind, what is needed in such situations is a halfway house: something that respects the functionality of PureMVC, but which is free of the singletons and supports dependency injection (DI).
To that end, I decided the best solution was to take the PureMVC source and modify it to meet these requirements. My aim was to make as few changes to PureMVC’s behaviour whilst making the following changes:
- Get rid of the Facade class (I dislike this need to bolt a fourth corner onto the MVC triangle)
- Get rid of the singletons and server locator features and replace them with a simple, portable, DI solution.
- Improve some small aspects of the code, such as making the Observer and Notification classes true – immutable – value objects and by using properties where possible.
- Move the Observer handling code out of View (why was it ever put there?) into Controller
Having made those changes, I then modified the AS3 PureMVC test cases to handle the changes (eg injecting an instance of Controller into the test objects) and ran the tests to ensure I’d not broken any functionality.
The result of this is WiseMVC. At its heart is the Controller class. Creating an instance of this also creates an instance of View and Model, both of which can be accessed via the controller object. Observers remain at the heart of the system, as before. Mediators, Commands and Proxies all remain, but they now all take an instance of Controller as their constructor’s first parameter. This achieves dependency injection in the simplest way possible.
At the moment, this code remains very much beta. It still has many of the PureMVC ASDoc comments for example. I plan on testing it on a large application to ensure it works and need to tidy up the comments. At that stage, I’ll put it on something like github.
In the meantime, I’m interested in feedback from others. To that end the WiseMVC source can be downloaded here. Please feel free to download it and take a look and then point out anything I might have forgotten, messed up etc. 🙂