Parsley Model-View-Mediator Architecture

POSTED IN Design, Flash Platform, Flex | TAGS : , , , , , , , July 12, 2010

For those who have used Parsley as their application framework knows just how powerful it can be. However, there is something that has annoyed me slightly over time.

When I’m designing a system, I always try to use proper Flex practices. Practices like using MVC to separate components and business logic, making components truly encapsulated and reusable, etc. The problem that I find with Parsley is that it only allows you to use Injection based views for its MVC architecture; the View knows something, either a Presenter or a Model, and it’s always injected in by the Context.  The problem is, if you have several projects that need the same components but different frameworks, you can’t freely interchange those components between projects since the view is tightly intertwined with the Parsley injection.

A way to solve this by using the Mediator pattern (The View knows nothing, but the Mediator knows about the View) because it makes your view extremely portable between projects and forces the developers to use better practices since the only way to communicate with the Mediator is through events.

Luckily, Parsley has several extension points which you can insert custom classes to change or add functionality.  This gave me an opportunity to create my own parsley tag aptly named ‘Mediator’.  What this allowed me to do is to create a Mediator class that is controlled by Parsley and when the view is created; an event would get dispatched from the View and Parsley would then create a Mediator class and inject the view into it.  This way, the view never knows anything about the framework which leaves the components to be freely interchangeable between projects.

WARNING: The following code only works with Parsley 2.3 and higher.  I made it this way because some major changes have been made to the extension points in 2.3.

You can download the sample application I made and look at the files. All you really need is the Mediator library swc and put it in your project.  Then you need to specify that you Parsley context will use this Mediator extension by doing the following.

<!-- Initialize Parsley like you would normally -->
<spicefactory:ContextBuilder config="{Config}">
	<!-- Except add the mediator configuration within it -->
	<!-- Alternatively, you can use Mediator.initialize(); instead of the mxml tag -->
	<mediator:Mediator />
</spicefactory:ContextBuilder>

And that’s it. By including the Mediator class within your Context, Parsley knows how to change the extension point for it to work.

UPDATE: Instead of giving you the raw files, I’ve packaged them in an easy to use library.  You can now find the source for the library here.

UPDATE 2: I’ve updated the files for the latest 2.3M3 changes in Parsley.

UPDATE 3: Parsley 2.3 came out recently and I’m happy to say that my Mediator still works.

UPDATE 4: Parsley 2.4 is out and I’ve updated the mediator and added it to GitHub.

12 COMMENTS

  1. Sam says:

    This is a very cool idea and promising library! I have found a couple issues using it, however. Parsley 2.3M3 breaks support due to an API change in DefaultViewManager. Also, I think AbstractMediator should extend EventDispatcher. If there were a public repository I would be happy to send patches.

  2. I’m not a fan of creating more EventDispatchers if parsley can already inject the framework dispatcher in the class. I guess if you create your own dispatcher it’s easier to handle which events gets caught by Parsley, but all the events I fire from this class is caught by Parsley. It’s a matter of preference. As for this not working with 2.3M3, Jens must of changed something again in the extension points. I’ll be sure to update.

  3. Sam says:

    I took your advice and I used an injected message dispatcher function instead. It solved a problem I had, where events dispatched in the [Init] method in my mediator were being fired before Parsley had a chance to wire a DynamicCommand defined in the context 90% of the time.

  4. Aaki says:

    Is there a version of mediator available for parsley 2.4?

  5. Actually, a friend of mine patched it for 2.4. I will post it up as soon as he sends it to me. Cheers.

  6. Alright, updated the code and placed it on GitHub. Cheers.

  7. [...] Boudreau has written what looks to be an excellent Mediator extension for Parsley, that allows a mediator class to attach itself to a view when the view is initialised.   The end [...]

  8. Tihomir says:

    Hi, I’m having some problems using this extension. initView() method in the mediator is triggered different number of times in different occasions, so it’s sometimes triggered two times, sometimes one (as it should I believe) and sometimes it’s not triggered at all. Did anybody else experienced this problem?
    Btw, very good extension.
    Cheers

  9. Hey Tihomir,

    I would be glad to help you. Could you pastebin what you’re trying to do (the mediator, the view and the context) and I can suggest how to fix it.

  10. Ceas says:

    Although I understand what you are saying about components being tied to the framework by depending on the context to inject something. I for one usually make it a point to only have my framework actors be it mediator or pm limited to  my project screens/views (the containers). These will then hold and pass through any data to any reusable components I would have inside them.  I would think in most cases the containers would be specific the one project but I guess every situation is different as well. Thats the approach I usually take.  

    On another note. This looks like a good solution to my mobile application issue. basically I feel someone what uncomfortable with one View telling the navigator what the next View to load is. especially after an async command. with this i can just have a mediator for the view navigator take care of that for me. I couldn’t see how a presentation model would handle that while needing a reference to the actual navigator. 

    What do you think?

  11. You could do it with a presenter. Both ways can work, but if I were you, I’d look at the pros and cons of both patterns. Like I said in the article, I used a Mediator pattern for a very specific reason, but both can the do the same work in essence. In your case, I would image you’d want a ‘NavigationPresenter’ of sorts that can listen for those async events and then decide what to do from there. I don’t know exactly what your requirements are, but I’m sure that there is a reasonable way of doing this. You could have some sort of config that says “if event X is dispatched, show view Y”.

  12. Ceas says:

    Yea, its been a while and I started thinking about just having something like what you mentioned, a NavigationPresentor. Just really wanted something outside of my other presentors that could have access to the navigator  to push the view.  

    thanks.

Loading