Découverte du MVC dans Pixlib

Voici un petit article qui décrit l’organisation MVC d’un projet Pixlib 3.0.

Ce n’est pas un hasard, si le pattern MVC est décliné dans de nombreux langages et présent dans le coeur de la plupart des framework orientés applicatif. La découpe d’un projet sous la forme Modèle-Vue-Contrôleur apporte beaucoup de souplesse et donc un gain de temps non négligeable dans le maintien et l’évolution d’une application.

Courte synthèse sur le pattern Modèle-Vue-Contrôleur

Le MVC est un modèle de conception qui regroupe les classes d’une application en 3 groupes :
• le groupe des Modèles, qui correspond au code permettant de gérer et manipuler les données ;
• le groupe des Vues, qui rassemble tout ce qui sert d’interface avec laquelle l’utilisateur va interagir ;
• le groupe des Contrôleurs, qui traite les événements et notifie qui de droit des changements éventuels.

Bien que très formelle, l’organisation d’un projet sous forme de MVC offre une structure propre et solide. Plus de détails sur l’article de Wikipedia : Modèle-Vue-Contrôleur

Le MVC dans Pixlib peut aussi être appelé MVC+FC (Model-View-Command+FrontController), car la partie contrôleur est composée d’un FrontController et d’un ensemble de Commandes.

Le MVC est global dans Pixlib

Organisé autour de 3 Locators globaux, basés sur une logique de Singleton (Singleton(patron de conception)), le MVC « made Pixlib » permet d’atteindre de manière globale chaque élément de l’application.

Chaque Locator est un agrégateur :

  • le PXModelLocator agrège les PXModel ;
  • le PXViewLocator agrège les PXView ;
  • le PXFrontController agrège les PXCommandes.
PXView, PXModel et leurs Locators.

Le groupe des vues et des modèles fonctionne de la même manière.
PXView et PXModel sont des interfaces, qui possèdent une implémentation abstraite (Classe abstraite) (PXAbstractView et PXAbstractModel) que l’on va étendre pour en faire un usage concret.

Donc en pratique, chaque vue doit étendre la classe PXAbstractView;

public class MyView extends PXAbstractView
{
	public function MyView(viewName : String)
	{
		super(null, viewName);
	}
}

et chaque modèle doit étendre la classe PXAbstractModel.

public class MyModel extends PXAbstractModel
{
	public function MyModel(modelName : String)
	{
		super(null, modelName);
	}
}

Ces deux classes prennent comme arguments dans le constructeur : le owner que nous laisserons pour le moment à null (pour en savoir plus rendez-vous sur : La notion de Plugin, le multi-MVC dans Pixlib), et le name qui servira d’identifiant unique.

Lors de l’instanciation de ces classes, l’argument name va être utilisé comme identifiant unique par le locator (PXModelLocator pour MyModel et PXViewLocator pour MyView). Ce qui va nous permettre de récupérer les instances de modèles et de vues depuis n’importe quel endroit de notre application.

// stockage implicite dans les Locators faits lors de l'instanciation
new MyModel("idUnique");
new MyView("idUnique");
 
// qui permet une récupération des instances de manière globale.
PXModelLocator.getInstance().locate("inUnique"); // retourne l'instance de MyModel
PXViewLocator.getInstance().locate("inUnique"); // retourne l'instance de MyView
PXCommandes et PXFrontController

Légèrement différent, PXFrontController permet de lier des commandes à un identifiant et de les exécuter selon nos besoins.
Tout comme les modèles et les vues, les commandes ont une interface PXCommand et une implémentation Abstraite PXAbstractCommand qu’il faudra étendre pour l’utiliser.

Le code de base d’une commande est donc :

public class MyCommand extends PXAbstractCommand
{
	override protected function onExecute(event : Event = null) : void
	{
		// notification de fin d'exécution, car commande asynchrones!
		fireCommandEndEvent();
	}
}

Pour pouvoir l’utiliser via le contrôleur, nous devons ajouter MyCommand au PXFrontController, en utilisant un EventType comme identifiant unique.

var controller : PXFrontController = PXFrontController.getBaseController();
controller.pushCommandClass("onCommand", MyCommand);

Ce qui nous permettra depuis n’importe quel endroit de lancer l’exécution de la commande en passant au FrontController un événement qui a comme EventType l’identifiant de notre commande.

PXFrontController.getBaseController().handleEvent(new Event("onCommand"));

À noter que les commandes dans Pixlib sont asynchrones, ce qui oblige d’appeler la méthode fireCommandEndEvent() pour notifier la fin de leurs exécutions.

Qui communique avec qui ?

Maintenant que vous savez instancier et récupérer les modèles, vues et commandes au sein de Pixlib, voyons comment organiser tout ce petit monde dans une application.

Des modèles vers les vues

Le couplage faible est un maitre mot dans un projet Pixlib.
C’est pour cette raison que l’organisation de la communication entre les modèles et les vues est gérée depuis l’extérieur.

var view : PXView = new MyView("MyView");
var model : MyModel = new MyModel("MyModel");
model.addListener(view);

Les modèles ne connaissent pas les vues et vice versa.
La communication se passe via le système événementiel et la notification de changement.

En pratique, lorsqu’un modèle subit un changement, il le notifie.

public class MyModel extends PXAbstractModel
{
	public function change() : void
	{
		logger.debug("Model change", this);
		notifyChanged(new PXStringEvent("onChange", this, "ma nouvelle String"));
	}
}

La ou les vues abonnées au modèle reçoivent cette notification et réagissent en conséquence.

public class MyView extends PXAbstractView
{
	public function onChange(event : PXStringEvent) : void
	{
		logger.debug("Model send me new string " + event.value, this);
	}
}
Des vues vers les commandes

Principal point d’entrée des applications, les vues sont en général à l’origine de l’exécution des commandes.
Grâce à la méthode firePrivateEvent, les vues peuvent exécuter n’importe quelles commandes agrégées sur le PXFrontController du MVC.

// agrégation de la commande « MyCommand » sur le PXFrontController
var controller : PXFrontController = PXFrontController.getBaseController();
controller.pushCommandClass("onCommand", MyCommand);
// exécution de MyCommand depuis une vue
firePrivateEvent(new Event("onCommand"));
Les commandes vers les modèles ou les vues

Étant les gestionnaires de l’application, les commandes permettent de modifier des vues, des modèles ou l’exécution de nouvelles commandes.

public class CheckCommand extends PXAbstractCommand
{
	override protected function onExecute(event : Event = null) : void
	{
		// modification d'un modèle
		getModel("MyModel").release();
		// modification d'une vue
		getView("MyView").show();
		// execution d'une autre commande
		firePrivateEvent(new Event("onChange"));
 
		fireCommandEndEvent();
	}
}

En résumé :

  • le MVC dans Pixlib est global ;
  • chaque groupe de classe possède un Locator (PXModelLocator pour les modèles, PXViewLocator pour les vues, PXFrontController pour les commandes) ;
  • les modèles notifient les vues ;
  • les vues lancent des commandes ;
  • les commandes permettent de modifier les modèles et/ou les vues, ainsi que l’exécution de nouvelles commandes ;

 

Pour continuer :

 

Happy codding with Pixlib!

This entry was posted in Core, Framework, Tutorial. Bookmark the permalink.

One Response to Découverte du MVC dans Pixlib

  1. Pingback: La notion de Plugin, le multi-MVC dans Pixlib | Pixlib Flash Platform Framework

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" cssfile="">