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.”
But if we search for MVC frameworks, we find many variants: MVC1, MVC2, MVC3, MVP, MVVM and PureMVC.
The question is which one is the best to use?
As any debate like that, there’s no unique solution, it depends on many factors. In this article, we try using JavaDepend to discover PureMVC indepth, 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 later to many other languages. The following GWT sample uses the Java PureMVC Framework, let’s analyze it to explore 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 namespace, to modularize better the application.
Here’s the graph representing the communication between all namespaces.
There’s no dependency cycle, it’s well layered, that makes it very clear and simple to understand.
The matrix gives us more details about dependency weight between all namespace
s.
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 uses the publish-subscribe pattern to communicate between all actors (Model, View, Controller), 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 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 receive 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 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 other.
Here’s a concrete example of adding a new user from view.
In this sample, the mediator asks the proxy to add a user and later sends a notification to inform all other components that a user was added.
What’s interesting to note here is the fact that the mediator communicates directly with the proxy, in PureMVC, proxies can't act as subscribers, and can only publish notification.
Inside PureMVC Concepts
Facade
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
instantiates it, but 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 Initialisation
SELECT METHODS WHERE
IsDirectlyUsedBy "org.puremvc.java.multicore.patterns.facade.Facade"
The facade initializes all other actors.
Facade and Notification
The facade caches all actors, and when a notification is published, the facade notifies all observers.
Commands
Let’s search for all methods used by DeleteUserCommand
, the command responsible for 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.
Mediators
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.
Proxies
The question that makes a difference using PureMVC and gives us three more other variants is:
Who communicates 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 exists in mediator instead of command, we have to duplicate the code if another mediator needs 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 to 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 in which all actors communicate with each other, PureMVC chooses the asynchronous and the less coupled solution.