Fondamentaux d'architecture d'une application Flex Adobe eSeminar - 06/06/08 David Deraedt Centre Regart.net
Introduction Comment organiser le code d'une application Flex ? Ne sont pas concernés : Démonstrations Exemples Très petites applications Généralement : Enjeu commercial Utilisateurs "réels" Durée de vie importante Travail en équipe (?)
Contraintes Constat : Maintenance > Développement initial Méthodes agiles = cycles courts, itératifs Faciliter : Modifications Tests / Débogage Travail en équipe Productivité
Bonnes pratiques Séparer les responsabilités Dans le code Dans l'équipe Limiter le couplage Indépendance Modularité Partager Informations (Méthodologie et terminologie, documents) Outils (factorisation, mutualisation)
Mise en oeuvre POO Encapsulation Polymorphisme Design patterns Architecture patterns Contexte technologique Flex = RIA = Couche présentation d'une architecture 3 tiers
Rich Internet Application Architecture 3 tiers Rich Internet Application Architecture RIA: Client s'exécute sur poste client Client conscient de son état, "stateful" Le client connaît les détails d'implémentation du serveur Architecture plus "client / serveur"
Rich Internet Application Répartition des rôles Client / Serveur Serveur d'application = règles métiers Client riche = relation à l'utilisateur Quelle architecture côté serveur ? Présentation : Client Riche Intégration : Business Objects via des Services Persistance (ORM) : VOs / DTOs, DAO, ActiveRecord, ...
Rich Internet Application
Rich Internet Application Le client (RIA Flex) communique avec : L'API du service (parfois, directement DAOs) Les VOs / DTOs Mais de quelle manière ?
Communication Avec Flex, deux familles d'outils : Communication temps réel Communication RPC asynchrone RPC : HTTPService WebService RemoteObject
HTTPService Requêtes HTTP(s) URLencoding, (couple identifiant/valeur voire XML) Script / Page ASP, JSP, PHP, ... Services REST Les données échangées ne sont pas typées. => Intérêt limité à de "petites" tâches individuelles - Upload de fichiers, création de fichiers, Proxies, etc... ou => JSON (typage des données)
WebService Au sens SOAP Envoie / reçoit SOAP (XML) Web Service Definition Language (WSDL) Echanges de quelques données "typées" : Types primitifs AS3 (Boolean, int, uint, Number, String, ...) Quelques types complexes du top level (Array, Date) Sérialisation/ Désérialisation côté Flex Pas de type personnalisé
RemoteObject Remoting : AMF : ActionScript Message Format = AS binaire HTTP(S) ou protocoles temps réél AMF3 = AS3 (Flex), AMF0 = AS1 + AS2 Spécifications ouvertes Avantages Performance (car binaire), cf Census Confort de développement car... Données typées Types primitifs Types complexes Top Level (selon passerelle) Types personnalisés : Value Objects ([RemoteClass]) ... = 100 % POO !
RemoteObject Inconvéniant : Nécessite une passerelle AMF3 côté serveur (Sérialisation / Désérialisation AMF3) Solutions gratuites et OpenSource pour toutes technos J2EE : BlazeDS, WebORB, GraniteDS, LCDS(ES) .NET : Fluorine, WebORB PHP : AMFPHP, WebORB, SABREAMF ROR : RubyAMF, WebORB Python : PyAMF Perl : ?
Architecture côté Flex A priori : hiérarchie de composants MXML. Sommet de la pyramide = Document principal (Application, WindowedApplication, Module) Les composants : Représentent les données graphiquement Reçoivent l'interaction utilisateur => C'est la vue d'un MVC Ces vues peuvent elles être indépendantes ? Qui va s'occuper du reste (logique de l'application) ?
Indépendance des composants Permise par 2 Mécanismes fondamentaux : DataBinding = Mise à jour des données automatisée (Model -> View) Evénements = Transmission l'interaction utilisateur (View -> Controller) Note : attribut source de la balise Script "Code Behind" purement formel => Insuffisant
Limites du framework Flex Cas classique : le document principal gère toute la logique de l'application ! Conséquence : Vues bien découplées Reste de l'application très monolithique (code spaghetti) Conclusion: Reste la solution la plus simple pour de "petites" applications Très vite limité
Un MVC côté Flex
Un MVC côté Flex : Le modèle Stocke les données Ne sait pas comment elles sont représentées C'est l'état de notre application Aucune logique (sauf accès aux données) Souvent, simple liste de propriétés publiques VOs, ArrayCollections Tout est "Bindable"
Un MVC côté Flex : Le modèle
Un MVC côté Flex : Le contrôleur Cerveau de l'application Logique entre vue et modèle Ecoute les événements diffusés par les vues Met à jour le modèle Ne connaît rien des vues Design pattern "Command" Déléguer les tâches à des objets (Commands) Command = logique derrière une User Gesture Permet de traiter chaque tâche comme un objet (historique, undo, ...)
Un MVC côté Flex : Le contrôleur
Un MVC côté Flex : Le contrôleur Problème de fond : Comment faire remonter les événements vers un Contrôleur ? Bubbling : s'appuie sur la display list (pas suffisant) Remonter parent par parent : clone(), dispatchEvent(event) => Difficile de faire quelque chose de propre ET standard
Un MVC côté Flex : Le contrôleur Parfois, besoin de mettre à jour une vue dans une commande Problème : Le contrôleur ne doit rien savoir de la vue Solution : Diffuser un événement écouté par un tiers qui, lui connaît la vue. (View Helpers, View Controlers ...)
Un MVC côté Flex : Le contrôleur
La couche métier Les commandes doivent communiquer avec le Service Risque de couplage entre les deux Déléguer à un objet la communication avec le Service Le "BusinessDelegate" : Expose l'API du Service en AS3 Encapsule l'implémentation de sa communication Transmet le résultat à un Responder (Command) Avantages Découplage entre Command et Service Typage, Intelliscence
La couche métier
Vue d'ensemble
Remarques Peut paraître abstrait et compliqué, mais Beaucoup de classes sont très simples Toutes les classes sont courtes et lisibles Pas nécessaire de tout utiliser Concerne la majorité des applications Méthodologie et terminologie commune Adapté aux méthodes agiles / itératives De plus, des outils peuvent nous aider Frameworks d'architecture Générateurs de code
Les frameworks d'architecture Ce sont des bibliothèques tierces (.swc) Pas indispensables... Mais difficile de faire sans ! Les deux cas les plus communs : Cairngorm PureMVC
Cairngorm Framework d'architecture Flex Créé par Adobe Consulting S'inspire des core patterns J2EE Le plus utilisé Implémentation Modèle : ModelLocator (Singleton) Type d'événement : CairngormEvent Pattern FrontController / Command ServiceLocator BusinessDelegate optionnel
Cairngorm Problèmes Difficile de faire communiquer Commandes et vues Risque de couplage des vues avec Cairngorm (event.dispatch()) Pas terrible avec les Modules Trop de Singletons => problèmes de tests Documentation faible Notes Beaucoup de ressources sur le Web Générateurs de code Cairngorm Extensions (Universal Minds)
PureMVC Framework AS3 (pas Flex, ni Flash) Créé par Cliff Hall Existe pour d'autres technologies Documentation de qualité et communauté active Implémentation Modèle : Proxies Contrôleur : Façade et Commands Evénements : Notifications Vues : Mediator
PureMVC Problèmes Pas de DataBinding entre Modèle et Vues Modèle événementiel non standard Plus de travail de Cairngorm Souffre de son éloignement vis-à-vis du framework Flex
Conclusion Privilégier une approche pragmatique Ne pas essayer d'appliquer une solution avant d'avoir rencontré le problème Ne pas avoir peur de la quantité de code : cela peut s'avérer rentable au final S'appuyer sur des techniques qui ont fait leurs preuves plutôt que de réinventer la roue Connaître un minimum Flex avant d'essayer les frameworks d'architecture Commencer par Cairngorm avant PureMVC
Questions / Réponses David Deraedt - Flex My Day http://www.dehats.com Centre de formation Regart.net http://www.regart.net Remerciements Lovely Charts http://www.lovelycharts.com