[pixLib] - Vues, Modèles, Contrôleur
Par Laurent Deketelaere le vendredi, octobre 27 2006, 18:28 - Flash plateforme - Lien permanent
Cela fait un moment que je voulais écrire cette article, mais je savais pas comment l'attaquer! Aujourd'hui je me lance, version «eXtrem programming», on verra bien ce qui va en sortir. :p
Mise en situation
Quand je pense à un projet typée "pixLib", je pense MVC global, c'est à dire que pour chaque partie, module, composant, je vais avoir une vue, un modèle et un contrôleur spécifique, jusque là rien de bien extraordinaire (pattern MVC), par contre ce qui est vraiment génial c'est que chaque partie est accessible de façon global.
En pratique
Au démarrage d'un projet je créé différents dossiers qui vont poser la structure.
- -- controllers
- -- events
- -- models
- -- uis
Le dossier «controllers»
Des commandes
Dans ce dossiers on va retrouver des classes qui implémentes l'interface Command, cette interface défini une méthode unique.
public function execute( e: IEvent ): Void;
Chacune de ces "Command" permet de définir une série de traitements que l'on voudra exécuter à un moment donné. — Design Patterns #4 : command pattern - Tweenpix
Un contrôleur
La classe Controller (extends FrontController) est le gestionnaire global des commandes, le cerveau de l'application. Implémenté généralement sous la forme d'un Singleton (car unique dans une application).
implémentation de base :
import com.bourre.events.FrontController; import net.geturl.project.controllers.RunProject; import net.geturl.project.events.EventList; class net.geturl.project.controllers.Controller extends FrontController { private static var _oI : Controller; public static function getInstance() : Controller { if (!_oI) _oI = new Controller(); return _oI; } private function Controller() { super(); } public function init() : Void { push( EventList.protectScreenEVENT, new Protectscreen() ); push( EventList.changeLanguageEVENT, new refreshLanguage() ); } }
// Flash spéciale
l'EventList est une classe qui liste l'ensemble des événements de l'application sous forme de propriétés statique.
exemple :
import com.bourre.events.EventType; class net.geturl.project.events.EventList { public static var changeLanguageEVENT:EventType = new EventType("changeLanguage"); public static var protectScreenEVENT:EventType = new EventType("protectScreen"); }
// fin du flash
Il faut savoir deux choses sur le FrontController, premièrement à l'instanciation il s'abonne au gestionnaire d'événements global "EventBroadcaster.getInstance()" le bien nommé, deuxièmement il permet de lier un EventType à une Command, c'est ce qui est fait dans la méthode init de la classe Controller.
public function init() : Void { push( EventList.protectScreenEVENT, new Protectscreen() ); push( EventList.changeLanguageEVENT, new refreshLanguage() ); }
Concrètement
Pour utiliser tous ce beau monde, il faut tout d'abord lancer la fonction init du Controller
Controller.getInstance().init();
Ensuite on peut à partir de n'importe quel endroit lancer une Command spécifique.
EventBroadcaster.getInstance().broadcastEvent( new BooleanEvent(EventList.protectScreenEVENT, true) ); EventBroadcaster.getInstance().broadcastEvent( new StringEvent(EventList.changeLanguageEVENT, "fr") ); EventBroadcaster.getInstance().broadcastEvent( new BooleanEvent(EventList.protectScreenEVENT, false) );
Que va-t-il se passer lorsque l'on va lancer un événement?
- l'EventBroadcaster envoi l'événement à toutes les classes abonnées (dont le FrontController/Controller)
- Si le Controller à une Command liée à l'EventType reçu, il va lancer la méthode "execute" de la Command.
NB. la méthode execute de la Command reçoit en paramètre l'événement, ce qui permet de lui envoyer des informations.
Le dossier «events»
Dans ce dossier je vais retrouver l'ensemble des mes événements typé, il s'agit de classes qui étendent la classe BasicEvent. pour plus d'info voir la FAQ de pixlib.
Les dossiers «models» et «uis»
Il s'agit des endroits où seront regroupé tout les modèles et les vues de l'application.
Je vais traiter ces deux type d'objets en parallèle car leur gestion global est basé sur le même principe.
Un modèle étend com.bourre.core.Model / Une vue étend com.bourre.visual.MovieClipHelper
Le premier argument de ces deux classes abstraites (Model et MovieClipHelper) est un identifiant unique (String). Implémentations basic des ces deux classes
Model
import com.bourre.core.Model; class net.geturl.project.models.UnModel extends Model { public function UnModel ( sID : String ) { super( sID ); } }
Vue
import com.bourre.visual.MovieClipHelper; class net.geturl.project.uis.UnUI extends MovieClipHelper { public function UnUI ( sID : String ) { super( sID ); } }
Lors de l'instanciation l'identifiant est ajouté à la liste global des Model ou des MovieClipHelper, ce qui permet après instanciation d'appeler les objets de n'importe quel endroit de l'application.
UnModel( Model.getModel("id") ).uneMethode(); UnUI( MovieClipHelper.getMovieClipHelper("id") ).uneMethode();
A noter, dans la pratique j'utilise deux classes UIList et ModelList qui sont basé sur le même principe que l'EventList, cad qu'elles regroupe l'ensemble des identifiants sous forme de variable statique.
UnModel( Model.getModel(ModelList.unModel) ).uneMethode(); UnUI( MovieClipHelper.getMovieClipHelper(UIList.uneVue) ).uneMethode();
Voilà, j'espère avoir été compréhensible dans mes explications, n'hésitez pas à poser des questions pour éclaircir certains points ou l'ensemble du sujet. :p
Bonne soirée
Derniers commentaires