According to MVC definition from wikipedia:
“Model View Controller (MVC) pattern creates applications that separate the different aspects of the application (input logic, business logic, and UI logic), while providing a loose coupling between these elements.”
In this article we try using JArchitect to discover the PureMVC in depth, and talk about the main difference between it and the other variants.
PureMVC was popularized first by Flex and Flash developers, but it was ported after to many other languages. The following GWT sample use the java PureMVC framework, let’s analyze it to explore the PureMVC concepts.
PureMVC basic Concepts
Here’s the structure of the project
This structure shows the main PureMVC concepts:
- Facade: Initializes and caches the core actors (model, view, and controller) and provides a single place to access all of them.
- Proxies: Expose an API for manipulating the data model ,including data retrieved from remote services.
- Mediators: The view communicates with their Mediators using Events and exposing some properties for the concrete Mediator to inspect or manage. A Mediator connects a View Component with its data and communicates with the rest of the system on its behalf.
- Commands: A Command may retrieve and interact with Proxies, communicate with Mediators, or execute other Commands. Commands are often used to orchestrate complex or system-wide activities such as application startup and shutdown.
The PureMVC best practices encourage developers to put each actor into a specific package, to modularize better the application.
The matrix gives us more details about dependency weight between all namespaces.
There’s no dependency cycle, it’s well layered what makes it very clear and simple to understand.
The PureMVC glue
To go deep inside the sample let’s discover the dependency graph between all classes
What’s interesting in this dependency graph, is that almost all classes uses INotification.
PureMVC use the publish-subscribe pattern to communicate between all actors(Model,View,Controler), and for this reason INotification is mainly used, and to check that let’s discover the most popular types, for that we can use the TypeRank metric.
SELECT TOP 100 TYPES ORDER BY TypeRank DESC, TypeCa DESC
The three most popular types concern notification mechanism, what’s proof that this concept is the glue of the PureMVC framework, almost all communication between actors use notification, that make them less coupled.
Publish–subscribe is a messaging pattern where senders of messages, called publishers, do not program the messages to be sent directly to specific receivers, called subscribers. Published messages are characterized into classes, without knowledge of what, if any, subscribers there may be. Subscribers express interest in one or more classes, and only receives messages that are of interest, without knowledge of what, if any, publishers there are.
This allows asynchronous, event-driven communications between the actors of the system, and also promotes a loose coupling between those actors, since the subscriber never needs to have direct knowledge of the publisher.
For our sample we can search for all classes using Notifier class to notify the other actors.
SELECT METHODS FROM JARS "PureMVC" WHERE IsDirectlyUsing "org.puremvc.java.multicore.patterns.observer.Notifier"
Almost all actors: Mediators, Commands and proxies use the notification mechanism to communicate with each others.
Here’s a concrete example of adding a new user from view.
In this sample the mediator ask the proxy to add a user and after send a notification to inform all the other components that a user was added.
What’s interesting to note here is the fact that the mediator communicate directly with the proxy, in PureMVC, proxies can’t act as subscribers, and can only publish notification.
Inside PureMVC Concepts
– Facade is singleton
If we search where the facade is instantiated
SELECT METHODS WHERE DepthOfCreateA "org.puremvc.java.multicore.patterns.facade.Facade" == 1
Only one static method getInstance instantiate it, this method has one parameter, so we can create many facades, each component has its own singleton facade identified by a name, and it’s why we talk about PureMVC MultiCore.
– Facade Initialization:
SELECT METHODS WHERE IsDirectlyUsedBy "org.puremvc.java.multicore.patterns.facade.Facade"
The facade initializes all the other actors.
– Facade and notification:
The facade caches all actors, and when a notification is published, the facade notifies all observers.
Let’s search for all methods used by DeleteUserCommand, the command responsible of deleting a user.
SELECT METHODS WHERE IsDirectlyUsedBy "org.puremvc.java.multicore.demos.gwt.employeeadmin.controller.DeleteUserCommand"
The command doesn’t communicate directly with other components, except for the proxy as we observed before.
SELECT METHODS WHERE IsDirectlyUsedBy "org.puremvc.java.multicore.demos.gwt.employeeadmin.view.UserFormMediator"
Like Commands, mediators use mainly notifications to interact with other classes except for proxies.
The question that makes a difference using PureMVC and gives us three more other variants is:
Who communicate with the proxy?
Here we can differentiate between three ways used by developers using PureMVC:
– Only Commands use proxies: we suppose that only commands have to abstract the logic of the application, this solution makes the code more reusable, for example deleteuser could be used by many classes, and if this logic exist in mediator instead of command, we have to duplicate the code if another mediator need to also delete a user.
– Commands and mediators use the proxy: For our sample it’s what happens, the AddUser is invoked from a mediator and the deleteuser from a command.
– Only Mediators use proxies and commands are used only for startup: Some developers prefer not use Commands and use only Mediators, to not add more classes and maybe more complexity to the code.
The main difference between PureMVC and the other variants, is the way that all actors communicate with each other’s, PureMVC choose the asynchronous and the less coupled solution.