Announcing WiseMVC: PureMVC without the anti-patterns

! Warning: this post hasn't been updated in over three years and so may contain out of date information.

wisemvcPureMVC has been a popular MVC framework. It is available for many programming languages. It’s lightweight, easy to learn and implements a nice interpretation of the rather vague concept that is “Model View Controller”. It’s popularity has begun to wane in recent years though for two reasons:

  1. 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.
  2. 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:

  1. Get rid of the Facade class (I dislike this need to bolt a fourth corner onto the MVC triangle)
  2. Get rid of the singletons and server locator features and replace them with a simple, portable, DI solution.
  3. 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.
  4. 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. πŸ™‚

6 thoughts on “Announcing WiseMVC: PureMVC without the anti-patterns

  1. Hi David, it’s a pretty good idea! I will try to take some time to check this on w-e.

    Immediate remark without having time to check the code :

    > using properties where possible

    this will not be possible in Java (so exclude Android). I prefer the idea to duplicate access to those method in each port where possible. In JavaScript, I admit that using myNotification.body instead of MyNotification.getBody() is a temptation each time. But it depends on the port, the best practices must not support accessign object with property to stay multi-language.

    >Observer and Notification classes true – immutable – value objects
    I don’t know hox you implement it, but same remark as above. It will be a problem with some languages.

    I found strange that you choose to create a different project than PureMVC. Why not asking Cliff to validate the idea to make an evolution to PureMVC. I’m pretty sure that if your project support PureMVC rules, Cliff and the community will follow your idea.

  2. @Tek,

    I thought long and hard about switching to properties. Then I looked at the Java and JavaScript implementations of PureMVC. The former has IFunction as a means of copying with the function references used by the Observer code. The latter has no interfaces and a set of prototypes instead of classes.

    These differences are of course through necessity, but the point is, there are already differences between the languages. Getting the right balance between using language features and remaining cross-language is hard. To my mind, PureMVC got it wrong with properties. I work for a company that uses Java and ActionScript. We adopt what to my mind is a sensible convention that many use: getX() and setX() in Java maps to x in AS3. It’s a simple convention and thus one that PureMVC probably should have adopted from the start.

    I may be mistaken, but I believe all the PureMVC languages support passing parameters via a constructor or the equivalent. All support accessing values from an object. Therefore all will cope with the value object model I use. Sure, they won’t be immutable in some languages, but that is the nature of those languages. The Notification class in PureMVC for example makes the name value read-only already. I just extended it to all values.

    I briefly spoke to @puremvc via twitter. I don’t know if that’s Cliff or not. That person seemed very hostile to the idea of abandoning the service locator pattern in favour of dependency injection. I therefore figured I’d start a new project, rather than try and convince the PureMVC crowd to change what they already had. To my mind, it makes it clearer to everyone what they are getting.

  3. I confirm that @puremvc is Cliff Hall in person.

    I agree with you that we have to use the best implementation possible from each language the framework is ported too. Using “x” in ActionScript and “getX()” seems a good approach.

    I’m looking forward to having time to try what you did. πŸ˜‰

  4. Is this something not to have included the as3 package in the namespace of your project? This could lead to problem with different languages coexisting in the same

    Virtual Machine instance like JVM or macro-languages like Haxe/JavaScript, Haxe/ActionScript. I prefer your convention not to use the language namespace for

    simplicity but I think that this is technically not suitable.

    For the property versus method access my preferred choice is now to simply have both every time possible.

    E.g on Proxy class:

    public function set data(value:Object):void
    public function get data():Object
    public function setData(value:Object):void
    public function getData():Object

    This is really not a problem in any way as this is located on a base class. And from my experience of switching often from one PureMVC language implementation to another, this is something really enjoyable to always look for the same methods name. This said, I’m pretty sure that beginners would be lost or some say that this is a cumbersome choice. So I’m still not sure what to choose.

    Considering your immutable implementation of Notifications I can’t find any issue regarding this. I don’t think that we have specific PureMVC extensions using setters on Notification as a feature. I suspected Pipes to do this but it uses a PipeMessage instead notifications.

    For the View observer implementation moved to Controller I think this is an error. The MVC paradigm says that the View must not know the Controller and your View has an instance of it for its Observer implementation. Same remark for your Model implementation, you have an instance of the Controller on it (not sure why although, I think this is just a test from your part).

    I do not have time to have a deeper look to the consequences of removing the Facade. In fact I want to test it a real multicore application that uses Pipes to say or not to say if this is definitely a good thing. For my part I like to have a Facade for each core, and I used the PureMVC Facade for this for commodity, but even Cliff tells me that this was not a good idea. So there’s great chance we don’t need the PureMVC Facade at all finally.

    PS: Sorry to have with Tek/Tekool I’m the only one indeed

  5. I removed the as3 from the package name as I couldn’t see any point to it. That is because I didn’t think it through properly though, such as with your example of multiple versions on one VM. However I do wonder why anyone would want multiple versions on one VM? I think it ought to be put back though.

    The idea of offering eg getName() and get name() where languages support it is an interesting one. I’ll have to think about that πŸ™‚

    Regarding the View and Model having access to Control, the argument “MVC paradigm says that the View must not know the Controller” is a nonsense with PureMVC, for it is accessible through the globally accessible facade. Of course by allowing all mediators and proxies access to the controller, they could modify commands, which ought to be (and probably is) a complete MVC “no no”. One way of dealing with it would be to make the command related methods protected. That way one could say have an application class extend it and set up the commands. View, Model and their associated classes would still have access to Controller, but with a reduced functionality.

    My worry here is that I’m not trying to create yet another MVC framework, I’m simply trying to address issues with PureMVC that are a barrier to testing. With PureMVC, everything has access to the Controller though the Facade. To maintain compatibility with PureMVC, I therefore inject Controller into everything. Sure this is both an MVC and IoC “code smell”, but it’s a pragmatic approach to maintaining compatibility.

  6. First, sorry for the formatting of my last message, I edited it offline and I don’t understand why, some words are even missing.

    From what I quickly saw, the View and Model knowing Controller is not a real problem as it is an Observer/Observed relation which MVC authorizes. You just have to implement IObserver in Controller. So instead of initializing View and Model with the concrete Controller, just initialize them with an IObserver object and this still with be “pure” MVC. πŸ˜‰

Comments are closed.