<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>La Fabrick &#187; cairngorm</title>
	<atom:link href="http://www.lafabrick.com/blog/tag/cairngorm/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.lafabrick.com/blog</link>
	<description>Laboratoire d&#039;interfaces riches (Flex, Flash, Air ...)</description>
	<lastBuildDate>Mon, 28 Nov 2011 22:02:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.4</generator>
		<item>
		<title>Cairngorm pour les fainéants&#8230; Tour d&#8217;horizons des code generator</title>
		<link>http://www.lafabrick.com/blog/2008/01/10/288-cairngorm-pour-les-fainants-tour-d-horizons-des-code-generator/</link>
		<comments>http://www.lafabrick.com/blog/2008/01/10/288-cairngorm-pour-les-fainants-tour-d-horizons-des-code-generator/#comments</comments>
		<pubDate>Thu, 10 Jan 2008 10:18:42 +0000</pubDate>
		<dc:creator>Lionel</dc:creator>
				<category><![CDATA[Logiciels / extensions / plugins...]]></category>
		<category><![CDATA[[Dev] Flash / Flex / AIR...]]></category>
		<category><![CDATA[cairngorm]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://92.243.2.196/lafabrick/blog/?p=288</guid>
		<description><![CDATA[<p>parce que Cairngorm c'est bien, mais c'est un peu long des fois...</p> <p>En fait, quand on utilise cairngorm dans un projet avec plusieurs commandes, et quelques écrans, ça devient vite le Bowdel, pour une commande, 2 voir 3 de fichiers à écrire, souvent les mêmes mais qui changent un peu, à 3 mots prêts... Donc au final, on gagne du temps parce qu'on utilise cairngorm et qu'on ré-invente pas la roue mais on en perds parce que c'est pas super pratique à utiliser... Je dirai que c'est le même combat pour des projets de Remoting, avec coté serveur, le développement des méthodes Création / Ajout / Suppression / Modification (CRUD) pour les objets (VO,DTO au choix) que l'on utilise dans notre appli...</p> <p>C'est la que les outils de générations automatiques du codes interviennent, plus ou moins bien fichus, plus ou moins bien intrégrés.</p>]]></description>
			<content:encoded><![CDATA[<p>parce que Cairngorm c&#8217;est bien, mais c&#8217;est un peu long des fois&#8230;</p>
<p>En fait, quand on utilise cairngorm dans un projet avec plusieurs commandes, et quelques écrans, ça devient vite le Bowdel, pour une commande, 2 voir 3 de fichiers à écrire, souvent les mêmes mais qui changent un peu, à 3 mots prêts&#8230; Donc au final, on gagne du temps parce qu&#8217;on utilise cairngorm et qu&#8217;on ré-invente pas la roue mais on en perds parce que c&#8217;est pas super pratique à utiliser&#8230; Je dirai que c&#8217;est le même combat pour des projets de Remoting, avec coté serveur, le développement des méthodes Création / Ajout / Suppression / Modification (CRUD) pour les objets (VO,DTO au choix) que l&#8217;on utilise dans notre appli&#8230;</p>
<p>C&#8217;est la que les outils de générations automatiques du codes interviennent, plus ou moins bien fichus, plus ou moins bien intrégrés.</p>
<p><span id="more-288"></span></p>
<p><strong>Pour Cairngorm</strong></p>
<p><a hreflang="en" href="http://www.ericfeminella.com/blog/2007/01/04/introducing-cairngen/">cairngen</a></p>
<p>Sous la forme d&#8217;une tache ANT, on peut, à partir d&#8217;un fichier properties, créer l&#8217;arborescence type de cairngorm, créer le ModelLocator, le Controller, le service Locator, des VO, et les sequences Event / commandes / Delegate, la totale quoi. Comme c&#8217;est une tache Ant, c&#8217;est parfaitement intégré à FlexBuilder / Eclipse. Ca prend 5min à configurer et ça fait gagner pas mal de temps. Pour ceux qui voudraient en apprendre un peu plus sur Ant, je vous invite à explorer les sources,  ça fournis un bon exemple pratique.</p>
<p><a hreflang="en" href="http://www.tylerbeck.com/CairngormCreator/">CairngormCreator</a></p>
<p>C&#8217;est un outil de génération en ligne, qui fournit une interface graphique. Il permet d&#8217;aller assez loin en terme de personnalisation, on peut en plus de toute la base (Arborescence Cairngorm, ModelLocator, Controller, &#8230;.)  créer des vues, et même les squelettes de classes qui seront dans un package Utility. Il fournit aussi un fichier de build pour compiler l&#8217;appli&#8230; il est même possible de visualiser les sources générées. Quand on a fini, on peut  télécharger une archive qui contient tous nos fichiers.</p>
<p><a hreflang="en" href="http://www.dehats.com/drupal/?q=node/7">FCG &#8211; Flex Cairngorm code generator</a> (par Dehats)</p>
<p>FCG est une appli Air. La différence avec les précédents outils, c&#8217;est qu&#8217;il est &laquo;&nbsp;intelligent&nbsp;&raquo;. Il peut lire les sources / java / php  de nos objets coté serveurs et il crée aussi les fichiers AS / Mxml qui vont bien, en plus des classes de bases de cairngorm. On a un outil bien complet et assez bien fait que j&#8217;ai malheureusement pas eu le temps de le tester, par contre, sur le site, on peut voir une démo en vidéo&#8230; ça donne envie,  ca à l&#8217;air d&#8217;être un bon outils pour préparer son projet Cairngorm. (A quand un outils, qui par de l&#8217;UML &#8230; )</p>
<p>Pour info, il existe aussi un générateur en ruby sur googleCode&#8230; mais je fais pas ruby !</p>
<p><strong>Coté serveur</strong></p>
<p><a hreflang="en" href="http://titaniclinux.net/daogen">DAOGen</a></p>
<p>La, rien a voir avec cairngorm, puisqu&#8217;on a que la partie objets serveur (+ connections à une BDD). Ici le point de départ, c&#8217;est la base de données. On crée des tables un peu comme avec phpMyAdmin.  On choisi son langage coté serveur (pour l&#8217;instant JAVA / PHP ) et au final, en plus des fichiers DAO dans le langage choisi, on a les fichiers SQL pour créer les tables&#8230; la classe !</p>
<p>Après, on a aussi des truc genre La Grosse Berta, qui font le flex, le partie serveur&#8230; pas encore le café&#8230; mais bon on leur fait confiance ça devrait pas tarder&#8230;</p>
<p><a hreflang="en" href="http://www.crazedcoders.com/php/codegen.php">Simple CRUD code generator</a></p>
<p>Génération en ligne, le générateur se connecte à votre base et génère les classes php (5) des VO, les classes qui gèrent les transactions&#8230; le tout pour après faire du remoting avec amfphp1.9.</p>
<p><strong>Et quelques mots pour conclure&#8230;</strong></p>
<p>Le premier point, c&#8217;est que c&#8217;est des outils, pas autres choses, ils codent pas à notre place. Leur but est juste de supprimer des parties redondantes ou commune à la mise en place de projet Cairngorm, utilisant du Remoting ou pas&#8230;</p>
<p>De mon point de vue, le plus important dans ces outils, c&#8217;est leur rapidité d&#8217;utilisation, faut pas qu&#8217;on passe 3 heures à tout configurer aux petits oignons pour avoir une génération parfaite. Je pense qu&#8217;on gagne plus de temps à avoir une génération &laquo;&nbsp;presque parfaite&nbsp;&raquo; mais qui nécessite beaucoup moins de temps de préparation, et pour ca j&#8217;aime bien cairngen, car après l&#8217;avoir personnalisé, on modifie 10 lignes dans un fichier properties et c&#8217;est parti&#8230; par contre il fait que la partie flex. J&#8217;aime bien aussi l&#8217;approche de parti de la base de donnée pour généré ce qu&#8217;il faut coté serveur.</p>
<p>En tout cas après ça, si vous utilisez pas cairngorm&#8230; c&#8217;est que que vous avez une bonne raison !Autres articles sur le même sujet
<ul>
<li><a href="http://www.lafabrick.com/blog/2007/11/15/266-debuguer-un-projet-flex-distant-via-flex-builder/" rel="bookmark" title="15 novembre 2007">L&#8217;erreur est humaine&#8230; debuguer un projet Flex distant via Flex Builder</a></li>
<li><a href="http://www.lafabrick.com/blog/2007/10/03/256-titre/" rel="bookmark" title="3 octobre 2007">Utiliser Cairngorm dans un projet Flex / AMFPHP</a></li>
<li><a href="http://www.lafabrick.com/blog/2008/02/06/301-tips-of-the-day-les-collectionevent/" rel="bookmark" title="6 février 2008">Pti truc du jour : Les CollectionEvent</a></li>
<li><a href="http://www.lafabrick.com/blog/2008/01/15/291-flex-masquer-les-warnings-inutiles/" rel="bookmark" title="15 janvier 2008">Flex et les warnings inutiles&#8230;</a></li>
</ul>
<p><!-- Similar Posts took 14.987 ms --></p>
]]></content:encoded>
			<wfw:commentRss>http://www.lafabrick.com/blog/2008/01/10/288-cairngorm-pour-les-fainants-tour-d-horizons-des-code-generator/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Utiliser Cairngorm dans un projet Flex / AMFPHP</title>
		<link>http://www.lafabrick.com/blog/2007/10/03/256-titre/</link>
		<comments>http://www.lafabrick.com/blog/2007/10/03/256-titre/#comments</comments>
		<pubDate>Wed, 03 Oct 2007 17:18:28 +0000</pubDate>
		<dc:creator>Lionel</dc:creator>
				<category><![CDATA[[Dev] Flash / Flex / AIR...]]></category>
		<category><![CDATA[cairngorm]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Tutoriels]]></category>

		<guid isPermaLink="false">http://92.243.2.196/lafabrick/blog/?p=256</guid>
		<description><![CDATA[<p>Voilà un premier article sur le framework architectural d'Adobe , le bien nommé mais imprononçable Cairngorm MicroArchitecture... cet article est basé sur la série de 6 articles écrits par Steven Webster, un des papa du machin. Cet article s'adresse plutôt aux gens qui ne connaissent pas Cairngorm mais qui ont déja quelques notions de patterns (si vous savez que ça existe, je considère ça comme une notion )</p>]]></description>
			<content:encoded><![CDATA[<p>Voilà un premier article sur le framework architectural d&#8217;Adobe , le bien nommé mais imprononçable Cairngorm MicroArchitecture&#8230; cet article est basé sur la série de 6 articles écrits par Steven Webster, un des papa du machin. Cet article s&#8217;adresse plutôt aux gens qui ne connaissent pas Cairngorm mais qui ont déja quelques notions de patterns (si vous savez que ça existe, je considère ça comme une notion )</p>
<p><span id="more-256"></span><br />
<strong>Mise à jour</strong></p>
<p>L&#8217;archive des sources contient désormais un petit truc en plus qui permet de spécifier le endpoint depuis un fichier xml. on est plus obligé de recompiler à chaque fois !!!<br />
Dans cet article, nous allons aborder plusieurs points. Pour commencer : un cadrage sur Cairngorm, qu&#8217;est ce que c&#8217;est, qu&#8217;est ce que çà permet&#8230; Ensuite nous verrons au travers d&#8217;un exemple ( le classique Carnet d&#8217;adresse ), comment utiliser Cairngorm dans un projet Flex / AMFPHP. Vous aurez besoin de :</p>
<ul>
<li><a hreflang="en" href="http://labs.adobe.com/technologies/flex/">Flex 3 beta 2</a></li>
<li><a hreflang="en" href="http://labs.adobe.com/wiki/index.php/Cairngorm">Cainrgorm</a></li>
<li><a hreflang="en" href="http://www.5etdemi.com/blog/archives/2007/01/AMFPHP-19-beta-2-ridiculously-faster/">AMFPHP 1.9</a></li>
</ul>
<p>L&#8217;exemple de cette article peut être réalisé dans un environnement classique ( Flex Builder / éditeur PHP ) ou dans un eclipse tout intégré (plugin FlexBuilder 3 et PDT ). Nous reviendrons dans un autre article sur l&#8217;installation de ce dernier.<br />
Plutôt que de se jeter la tête la première dans Flex et le codage de notre RIA avec Cairngorm, faisons d&#8217;abord les présentations. Cairngorm est un <q>framework architectural</q> en partie basé sur le pattern Model-Vue-Controller, il va donc fournir aux développeurs un squelette sur lequel <strong>bâtir</strong> leur application ( en quelque sorte les <strong>fondations</strong> ). Cela permet par la suite une meilleure articulation du code en fonction des responsabilités de chaque &laquo;&nbsp;acteur&nbsp;&raquo;. Le développement de l&#8217;application va suivre certains <strong>plans</strong> qui nous permettront de mieux appréhender les évolutions futures de l&#8217;application (dans le meilleur des cas ),&#8230; ou au moins de nous donner un vision plus claire de notre code,  et de nous aider à trouver plus rapidement les bugs <img src='http://www.lafabrick.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
Cairngorm n&#8217;est donc pas un pattern, mais une <strong><q>micro architecture</q></strong>. On parle de micro architecture lorsque plusieurs modèles de conceptions (les patterns) collaborent, au sein d&#8217;une &laquo;&nbsp;composition&nbsp;&raquo; de patterns (MVC , FrontController ). Alors qu&#8217;un pattern est là pour résoudre un problème précis : <em>(comment m&#8217;assurer que j&#8217;ai bien une instance unique de telle classe dans mon application ? )</em>, la composition de patterns va permettre d&#8217;augmenter le niveau d&#8217;abstraction et de résoudre donc des problèmes de &laquo;&nbsp;plus haut niveau&nbsp;&raquo; : (<em>comment lier telle action de l&#8217;utilisateur avec un tel traitement</em>). Cairngorm utilise donc plusieurs patterns et les assemble pour nous permettre de mieux développer nos applications ( tout en nous évitant ainsi les risque de &laquo;&nbsp;patternite aiguë&nbsp;&raquo;, consistant à vouloir coller des patterns partout ). Cairngorm offre une micro architecture qui va permettre de résoudre les problèmes de conceptions récurrents dans le développement d&#8217;applications en ligne :</p>
<ul>
<li><strong>Récupérer les actions de l&#8217;utilisateur</strong></li>
<li><strong>Encapsuler la logique métier et les interactions avec le serveur</strong></li>
<li><strong>Gérer et représenter l&#8217;état de l&#8217;application côté client</strong></li>
</ul>
<p>Il existe une grande différence entre les applications web <q>classiques</q> et les <strong>RIA</strong>les premières sont &laquo;&nbsp;<strong>stateless</strong>&laquo;&nbsp;, les secondes &laquo;&nbsp;<strong>stateful</strong>&laquo;&nbsp;, c&#8217;est à dire que l&#8217;application conserve &laquo;&nbsp;l&#8217;état du client&nbsp;&raquo; durant les différentes transactions. En gros, quand le HTML &laquo;&nbsp;classique&nbsp;&raquo; doit recharger entièrement une page après chaque &laquo;&nbsp;appel serveur&nbsp;&raquo;, il est stateless ; alors l&#8217;une des caractèristiques des &laquo;&nbsp;applications riches&nbsp;&raquo; par contre, et de permettre des communications avec le serveur sans avoir à recharger entièrement la page en cours, elles peuvent donc être <strong>stateful</strong>. On sort en quelque sorte paradigme de la Page web, pour entrer revenir celui d&#8217;Application. Les RIA sont donc largement dépendantes des &laquo;&nbsp;modalités&nbsp;&raquo; de communication client / serveur, la difficulté résidant dans la capacités à envoyer/recevoir /afficher les bonnes données, au bon moment, et au bon endroit&#8230;<br />
Voyons donc maintenant comment Flex et l&#8217;AMF ( via AMFPHP dans notre exemple ), accompagnés de Cairngorm, nous permettent de gérer ces communications.<br />
L&#8217;AMF ( Action Message Format ) permet à Flex d&#8217;accéder à des objets côté serveur. Initialement destinée aux serveurs JAVA, cette &laquo;&nbsp;passerelle AMF&nbsp;&raquo; est utilisée par AMFPHP, pour accéder à des objets PHP via &laquo;&nbsp;services&nbsp;&raquo; PHP&#8230; mais çà vous le saviez !<br />
Penchons nous sur le rôle joué par Cairngorm : Cairngorm est une sorte de maquette d&#8217;application, il fournit un plan de construction et quelques pièces maîtresses. Ce plan est basé sur quelques d&#8217;objets ou types d&#8217;objets &laquo;&nbsp;spécialisés&nbsp;&raquo;, chacun ayant un rôle, ET ( &laquo;&nbsp;en principe&nbsp;&raquo; ) UN SEUL.<br />
Ces objets sont : les VO , le ModelLocator, les vues , le FrontController , les commandes, les delegates et le ServiceLocator. Ils vont entièrement articuler  le chargement des données côté serveur (PHP) et le traitement / affichage des données côté client ( Flex ).<br />
<img src="http://lafabrick.com/blog/images/Yo_cairngorm2.rtfd-20071003-173627.jpg" alt="" /><br />
Bon le générique c&#8217;est fait, passons à l&#8217;épisode du jour : créer notre &laquo;&nbsp;Rich&nbsp;&raquo; Carnet d&#8217;adresse.</p>
<p><strong>Les VO</strong><br />
Et au départ il y avait la poule ou l&#8217;oeuf ?<br />
Dans le cas de notre carnet d&#8217;adresse, l&#8217;objectif est de récupérer une liste de contacts, les afficher, les modifier, en ajouter &#8230; le 1er type d&#8217;objet échangé entre client et serveur sera donc le &laquo;&nbsp;(Contact)&nbsp;&raquo;.<br />
Pour le développement de RIA, on a en effet pas à réfléchir trop longtemps, au départ il y a le <strong>VO</strong> ou <strong>Value Object</strong> ( parfois appelé DTO, &laquo;&nbsp;Data Transfer Object&nbsp;&raquo; ). Le <strong>VO</strong> est le premier pattern qu&#8217;on rencontre dans Cairngorm. Il va nous permettre d&#8217;encapsuler dans un objet, toutes les informations correspondant à un enregistrement dans la base de donnée. Un VO n&#8217;est rien de plus qu&#8217;un objet contenant un ensemble de propriétés (une colonne de notre table dans la BDD correspondant à une propriété de notre objet ).<br />
Un des enjeux majeurs des RIA, puisqu&#8217;elles sont &laquo;&nbsp;stateful&nbsp;&raquo;, est d&#8217;être synchronisées avec le serveur. En effet à partir du moment où l&#8217;information se trouve à deux endroits, il y a un risque qu&#8217;un des &laquo;&nbsp;acteurs&nbsp;&raquo; ne soit pas &laquo;&nbsp;à jour&nbsp;&raquo;. Le VO va nous permettre d&#8217;augmenter le niveau d&#8217;abstraction en échangeant des objets qui ont un réel sens &laquo;&nbsp;sémantique&nbsp;&raquo; ( un &laquo;&nbsp;(Contact)&nbsp;&raquo; par exemple ), et non plus un sens du point de vue &laquo;&nbsp;technique&nbsp;&raquo; (un tableau de String). On a donc un modèle objet cohérent, et &laquo;&nbsp;identique&nbsp;&raquo; sur le client et sur le serveur. On s&#8217;éloigne de l&#8217;implémentation concrète, liée au langage de nos différentes couches (présentation, métiers, &#8230;).<br />
Vous allez vous dire &laquo;&nbsp;Mais c&#8217;est bien beau d&#8217;avoir nos objets d&#8217;un coté et de l&#8217;autre mais comment on fait pour les échanger..&nbsp;&raquo; Et bien tout çà ne serait pas merveilleux si l&#8217;on n&#8217;avait pas la possibilité de faire du &laquo;&nbsp;<strong>mapping</strong>&nbsp;&raquo; entre les objets clients et le objets serveurs. Ce mécanisme  permet lorsqu&#8217;on envoi un objet &laquo;&nbsp;ContactVO&nbsp;&raquo; ActionScript, de recevoir un objet du même type mais dans donc notre couche métier (qui peut être en PHP, en Java&#8230;). Cela facilite grandement les échanges entre le client et le serveur.<br />
Pour résumer, l&#8217;utilisation des <strong>VO</strong> permet :</p>
<ul>
<li><strong> de simplifier l&#8217;échange des données entre les différentes couches de l&#8217;application</strong></li>
<li><strong> d&#8217;augmenter le niveau d&#8217;abstraction en &laquo;&nbsp;encapsulant&nbsp;&raquo; les données dans des objets &laquo;&nbsp;métiers&nbsp;&raquo;</strong></li>
</ul>
<p>Notre 1er VO : <strong>ContactVO </strong></p>
<pre class="brush: js">
package com.lafabrick.Cairngormexemple.vo {
    [RemoteClass(alias=&quot;vo.ContactVO&quot;)]
    class ContactVO
    {
       public var id : int;
       public var nom : String;
       public var prenom : String;
       public var mail : String;
    }
}
</pre>
<p>Le mapping sera assuré grâce à la ligne  <strong>[RemoteClass(alias=<em>vo.ContactVO</em>)]</strong> ça veut dire que cette classe sera mappée côté serveur par la classe qui se trouve dans le package &#8216;vo&#8217; et qui s&#8217;appelle ContactVO mais on en est pas encore à transférer des objects entre le client et le serveur&#8230; on verra plus tard les joies et autres petits plaisirs du mapping.<br />
Très bien notre VO est identifié ! On sait quel type de données nous allons gérer. Voyons comment les intégrer à notre application.<br />
<strong>Le ModelLocator</strong> Cairngorm étant basé sur un MVC, qui dit &laquo;&nbsp;données&nbsp;&raquo;, dit &laquo;&nbsp;Model, et là on va pouvoir parler de &laquo;&nbsp;<strong>ModelLocator</strong>&laquo;&nbsp;.<br />
Parce que c&#8217;est bien beau d&#8217;arriver à échanger des objets entre le serveur et le client, mais on en fait quoi après&#8230; Cairngorm propose donc d&#8217;encapsuler  l&#8217;état ( des données ) du client dans une structure&#8230; je vous le donne en mille Émile&#8230; le ModelLocator. Et le ModelLocator reprends donc le concept du model de MVC.<br />
Le ModelLocator doit nous offrir un moyen de <strong>centraliser</strong> l&#8217;état du client plutôt que de le disperser un peu partout dans notre application. Du coup, il doit nous fournir aussi un moyen d&#8217;accès globalisé pour pouvoir accéder aux données qu&#8217;il contient. Les créateurs de Cairngorm insistent sur le fait que le ModelLocator doit contenir des objets ou collections d&#8217;objets qui sont porteur de sens (avec une sémantique associée). Dans un annuaire/ carnet d&#8217;adresses, on a des <em>Contacts</em>, des <em>Groupes</em>, des <em>Adresses</em>. Tiens çà vous rappelle rien ? Ben si ces entités seront sûrement les VO de l&#8217;application.<br />
<strong> CairngormExempleModelLocator</strong></p>
<pre class="brush: js">
package com.lafabrick.cairngormexemple.model {
     import com.adobe.cairngorm.CairngormError;
     import com.adobe.cairngorm.CairngormMessageCodes;
     import mx.collections.ICollectionView;
     [Bindable]
     public class CairngormExempleModelLocator
     {
         public var users : ICollectionView;
         private static var instance : CairngormExempleModelLocator;
         public function CairngormExempleModelLocator(  )
         {             if (instance == null)
             {
                 instance = this;
             }
             else
             {
                 throw new CairngormError(
                     CairngormMessageCodes.SINGLETON_EXCEPTION,
                         &amp;amp;amp;quot;CairngormExempleModelLocator&amp;amp;amp;quot;
                 );
             }
         }
         public static function getInstance() : CairngormExempleModelLocator
         {
             if (instance == null)
             {
                 instance = new CairngormExempleModelLocator();
             }             return instance;
         }
     }
 }
</pre>
<p>Pour ce qui concerne la vue, nous allons nous reposer sur un mécanisme de Flex assez pratique, <q>le Binding</q>. On a vu tout à l&#8217;heure que le ModelLocator devait nous fournir un accès globalisé aux données de l&#8217;application. Pour cela nous avons implémenté le modèle <q>Singleton</q>. Les plus perspicaces auront aussi remarqué le mot-clé <strong>[Bindable]</strong> qui va nous permettre, depuis un fichier mxml, de lier les données de notre Model aux propriétes d&#8217;un composant. La mise à jour des données dans l&#8217;application cliente sera largement simplifiée, puisqu&#8217;à partir du moment ou les données du modèle seront mises à jour, les vues branchées sur ces données bénéficieront des changements et cela automatiquement&#8230; pour pas une ligne de code&#8230; allons y c&#8217;est gratuit&#8230;<br />
Pour résumer, le <strong>ModelLocator offre un moyen globalisé d&#8217;accèder aux données de l&#8217;application.<br />
facilite la séparation données / vues  grâce  aux &laquo;&nbsp;Data Binding&nbsp;&raquo; </strong></p>
<p><strong>La Vue</strong><br />
Maintenant, on va créer la vue qui sera chargée d&#8217;afficher notre liste de contacts. Notre vue sera composée d&#8217;un Panel dans lequel sera affichée une Datagrid qui affichera nos objets Contacts. Et on va pas oublier de brancher le <strong>dataprovider</strong> de la datagrid sur la collection de &#8216;contacts&#8217; du model. Pour le moment, on ne va pas se casser la tête, on va directement poser notre composant vue ( le Panel datagridé ) dans notre fichier d&#8217;application principal.</p>
<pre class="brush: js">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;mx:Application xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot; layout=&quot;absolute&quot;
	xmlns:model=&quot;com.lafabrick.cairngormexemple.model.*&quot;
	xmlns:control=&quot;com.lafabrick.cairngormexemple.control.*&quot;
	xmlns:business=&quot;com.lafabrick.cairngormexemple.business.*&quot; initialize=&quot;initEventApp()&quot; applicationComplete=&quot;prepareApp()&quot; viewSourceURL=&quot;srcview/index.html&quot;&gt;
	&lt;mx:Script&gt;
		&lt;![CDATA[
			import com.lafabrick.cairngormexemple.event.UIEventList;
			import com.adobe.cairngorm.control.CairngormEventDispatcher;
			import com.adobe.cairngorm.control.CairngormEvent;

			public function initEventApp() : void
			{
				CairngormEventDispatcher.getInstance().addEventListener(UIEventList.FILE_CONFIG_LOADED,configLoaded);
			}

			public function configLoaded( event : CairngormEvent) : void
			{
				trace(&quot;config file loaded &quot;);
				services.contactService.endpoint = event.data;
				trace(&quot;endpoint : &quot; + services.contactService.endpoint );
				var e : CairngormEvent = new CairngormEvent(CairngormExempleControl.LOAD_CONTACTS_EVENT);
                e.dispatch();
			}

			public function prepareApp() : void
			{
				var e : CairngormEvent = new CairngormEvent(CairngormExempleControl.LOAD_CONFIG_EVENT);
                e.dispatch();
			}
		]]&gt;
	&lt;/mx:Script&gt;

	&lt;model:CairngormExempleModelLocator id=&quot;model&quot;/&gt;
	&lt;control:CairngormExempleControl id=&quot;controller&quot; /&gt;
	&lt;business:Services id=&quot;services&quot; /&gt;

	&lt;mx:Panel id=&quot;userpanel&quot; title=&quot;Mes contacts&quot; width=&quot;400&quot; height=&quot;300&quot; horizontalCenter=&quot;0&quot; verticalCenter=&quot;0&quot;&gt;
		&lt;mx:DataGrid dataProvider=&quot;{model.users}&quot; width=&quot;100%&quot; height=&quot;100%&quot;&gt;
			&lt;mx:columns&gt;
				&lt;mx:DataGridColumn dataField=&quot;nom&quot; /&gt;
				&lt;mx:DataGridColumn dataField=&quot;prenom&quot; /&gt;
				&lt;mx:DataGridColumn dataField=&quot;mail&quot; /&gt;
			&lt;/mx:columns&gt;
		&lt;/mx:DataGrid&gt;
	&lt;/mx:Panel&gt;
&lt;/mx:Application&gt;
</pre>
<p>Dans cairngorm, les responsabilités de la vue sont :</p>
<ul>
<li><strong>Gérer les interactions  avec les utilisateurs, et générer les événements associer.</strong></li>
<li><strong>Récupérer et mettre en forme les données contenues dans le ModelLocator en utilisant les DataBinding.</strong></li>
</ul>
<p>Sauf que pour l&#8217;instant y&#8217;a toujours rien à afficher&#8230;<br />
<strong>Le FrontController</strong><br />
Première chose pour gérer le chargement / envoi des données, on va créer ce qu&#8217;on appelle un . Le FrontController est en fait un modèle de conception composé du pattern MVC et du pattern Commande. Ce pattern va nous permettre de bénéficier d&#8217;une architecture capable de lier un type d&#8217;événement à l&#8217;exécution d&#8217;un traitement. Avant d&#8217;utiliser ce pattern, il faudra d&#8217;abord bien identifier les differents évenements qui vont être source de traitement. Pour notre exemple, on a choisi de réaliser le chargement de la liste de contacts depuis un base données au moment où l&#8217;application s&#8217;ouvrira.<br />
Le but du FrontController est de pouvoir encapsuler chaque traitement dans une classe (c&#8217;est l&#8217;utilisation de fameux pattern Commande ). Alors que le ModelLocator ne nous fournissait qu&#8217;une interface pour la création de notre modèle, cette fois Cairngorm nous fournit une classe presque complète. Nous allons donc créer une classe qui hérite de FrontController, et on va y énumérer les différents types d&#8217;évènements que l&#8217;application et ses vues peuvent générer. C&#8217;est toujours dans cette classe que l&#8217;on va associer un type d&#8217;évènement à une Commande particulière, une classe chargée du &laquo;&nbsp;traitement&nbsp;&raquo;. Pour notre carnet d&#8217;adresse, les différentes événements possible pourront être liés des commandes : d&#8217;ajout ou la suppression d&#8217;un contact, de chargement de la liste de VO&#8230; Pour le moment, nous savons juste qu&#8217;à l&#8217;ouverture de l&#8217;application, un événement CairngormExempleControl.LOAD_CONTACTS_EVENT est envoyé par l&#8217;application :<br />
<strong> CairngormExempleControl</strong></p>
<pre class="brush: js">
package com.lafabrick.cairngormexemple.control
{
    import com.adobe.cairngorm.control.FrontController;
    import com.lafabrick.cairngormexemple.commands.LoadConfigCommand;
    import com.lafabrick.cairngormexemple.commands.LoadContactsCommand;

    public class CairngormExempleControl extends FrontController
    {
        public function CairngormExempleControl ()
        {
            addCommand( LOAD_CONFIG_EVENT, LoadConfigCommand);
            addCommand( LOAD_CONTACTS_EVENT, LoadContactsCommand);
        }

        public static const LOAD_CONFIG_EVENT : String = &quot;&lt;load_config&gt;&quot;;
        public static const LOAD_CONTACTS_EVENT : String = &quot;&lt;load_contacts&gt;&quot;;
    }
}
</pre>
<p>C&#8217;est avec la méthode addCommand(EventType : String, MaCommande : ICommand) que l&#8217;on peut associer un type d&#8217;événement à un commande, et donc à un traitement. On a donc vu qu&#8217;utiliser le FrontController</p>
<ul>
<li><strong>nous permet de découper les responsabilité et les déléguées sur plusieurs acteurs</strong></li>
<li><strong>nous permet d&#8217;associer un type d&#8217;événement avec une commande</strong></li>
</ul>
<p><strong>Les Commandes </strong><br />
Il nous faut donc maintenant créer une Commande LoadContactsCommand. Elle aura pour mission de &laquo;&nbsp;commander&nbsp;&raquo; (le chargement de) la liste de contacts et de gérer sa réception ( ou sa non &#8211; réception ). Et comme Cairngorm est jusqu&#8217;au bout basé sur le principe de &laquo;&nbsp;délégation de responsabilité&nbsp;&raquo;, les Commandes délèguent l&#8217;appel serveur à une autre classe : la bien nommée Delegate. Lorsque qu&#8217;elles doivent récupérer des données sur le serveur, chaque commande dispose de sa propre classe Delegate ( dans notre exemple LoadContactsDelegate ). La Command est chargée de récupérer les données à envoyer au serveur ( si des données doivent être envoyées, elles sont stockées dans l&#8217;Event émis ), et de les transmettre au Delegate appropriée, qui elle, établira la communication avec le service concerné côté serveur. L&#8217;avantage de cette délégation est de garder les Commandes complètement indépendantes des opérations côté serveur.  Elles commandent des données, les réceptionnent, les traitent, mais ne savent pas d&#8217;où elles viennent. Si il y a le moindre changement du côté du serveur, elles ne sont pas  concernées.<br />
<strong>LoadContactsCommand</strong></p>
<pre class="brush: js">
package com.lafabrick.cairngormexemple.commands
{
	import com.adobe.cairngorm.commands.ICommand;
	import com.adobe.cairngorm.control.CairngormEvent;
	import com.lafabrick.cairngormexemple.business.LoadContactsDelegate;
	import com.lafabrick.cairngormexemple.model.CairngormExempleModelLocator;

	import mx.collections.ArrayCollection;
	import mx.rpc.IResponder;
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;
	import com.lafabrick.cairngormexemple.vo.ContactVO;

	public class LoadContactsCommand implements ICommand, IResponder
	{

		public function execute(event:CairngormEvent):void
		{
			trace(&quot;execute command LoadContacts&quot;);
			var delegate : LoadContactsDelegate = new LoadContactsDelegate( this );
			delegate.loadAll();
		}
		public function result(obj : Object) : void
		{
			var ev : ResultEvent = obj as ResultEvent;

			var u : ContactVO;

			CairngormExempleModelLocator.getInstance().users = new ArrayCollection(ev.result as Array);
			trace(&quot;result &quot;+ev.result);
		}
		public function fault(obj : Object) : void
		{
			var ev : FaultEvent = obj as FaultEvent;
			trace(&quot;error&quot;+ev.fault );
		}

	}
}
</pre>
<p>Notre commande implémente l&#8217;interface ICommand qui impose à la classe d&#8217;intégrer une méthode <em>execute(event:CairngormEvent):void</em>. Cela permet d&#8217;executer n&#8217;importe quelle commande puisqu&#8217;on aura pas besoin de savoir ce qu&#8217;elle fait, du moment qu&#8217;elle possède bien cette méthode execute(). Voici donc une partie du Design pattern &laquo;&nbsp;(Command)&nbsp;&raquo;.<br />
L&#8217;intérêt d&#8217;utiliser les commandes est :</p>
<ul>
<li><strong> d&#8217;encapsuler un traitement dans une classe</strong></li>
<li><strong> Dans le cas d&#8217;un appel distant, préparer les données nécessaires à la transaction et recupérer le résultat de la transaction</strong></li>
</ul>
<p><strong>Les Delegates</strong><br />
Pour charger notre liste d&#8217;utilisateur, nous allons utiliser AMFPHP (1.9) et les services de Flex. Pour éviter de mélanger les responsabilités, on utilise donc un objet LoadContactsDelegate qui sera chargé d&#8217;encapsuler les appels aux méthodes des services distants. C&#8217;est depuis cet objet que l&#8217;on établira la connection au service distant puis l&#8217;appel à la méthode distante qui nous renverra nos objets ContactVO. Cela nous permet par la même occasion d&#8217;avoir différentes commandes qui utilisent la même source de données en ayant chacune une spécificité au niveau du traitement. On appelle cela le <strong>Business Delegate</strong>.</p>
<pre class="brush: js">
package com.lafabrick.cairngormexemple.business
{
	import com.adobe.cairngorm.business.ServiceLocator;

	import mx.rpc.AbstractService;
	import mx.rpc.AsyncToken;
	import mx.rpc.IResponder;
	import com.lafabrick.cairngormexemple.vo.ContactVO;

	public class LoadContactsDelegate
        {
            private var responder : IResponder;
            private var service : AbstractService;

            public function LoadContactsDelegate( _responder : IResponder )
            {
                service = ServiceLocator.getInstance().getRemoteObject( &quot;contactService&quot; );
                responder = _responder;
            }

            public function loadAll( ): void
            {
                var token : AsyncToken = service.loadAll();
                token.addResponder(responder);
            }
	}
}
</pre>
<p>Les objets Delegate vont nous permettre</p>
<ul>
<li><strong>la prise en charge des connections aux services distants et les appels aux méthodes distantes</strong></li>
<li><strong>de cacher les logiques transactionnelles à la commande</strong></li>
</ul>
<p>Pour localiser notre méthode distante, on fait appel à un &laquo;&nbsp;<strong>ServiceLocator</strong>&nbsp;&raquo; qui va nous permettre de nous connecter à un service distant à partir d&#8217;un identifiant en utilisant la méthode getRemoteObject(). On verra plus bas comment utiliser le ServiceLocator pour référencer nos services distants. Pour appeller notre méthode distante, il nous suffit de l&#8217;appeller depuis notre objet service. Enfin, on utilise l&#8217;objet AsynToken pour pouvoir assigner un objet en tant que <em>Responder</em> qui sera alors chargé de gérer le résultat de notre méthode distante, et cet objet c&#8217;est notre commande, la boucle est bouclée, on revient à notre Commande. C&#8217;est pour cette raison que la Commande que l&#8217;on a créé implémente une deuxième interface : IResponder. Cette interface va permettre à notre Commande, lors de l&#8217;appel de la méthode distante, de réceptionner les événements <em>result</em> et <em>fault</em> afin de récupérer le resultat de la méthode si tout s&#8217;est bien passé ou dans le cas contraire, d&#8217;exécuter un gestionnaire d&#8217;erreur.</p>
<p>On vient donc de voir la séquence Evènement &#8211; Commande &#8211; Delegate. Il faut bien comprendre que l&#8217;emploi du Délégate est ici justifié par l&#8217;appel de méthodes distantes. Il est tout à fait envisageable d&#8217;avoir des séquences Evènement &#8211; Commande. Gràce à ce genre de découpage, rajouter une fonctionnalité revient à rajouter une commande (ainsi que son type d&#8217;événement associé). Ce découp(l)age nous permet aussi de bien séparer les responsabilités de chacun.<br />
Le mélange de FrontController, Command et Event et en fait lui même une &laquo;&nbsp;micro architecure&nbsp;&raquo; que l&#8217;on appelle Service To worker. Grosso modo on dégage la logique métiers des vues, on l&#8217;encapsule dans une classe et on utilise des évènements pour déclencher le tout à distance <img src='http://www.lafabrick.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /><br />
<strong> ServiceLocator </strong><br />
Nous avons donc besoin de récupérer nos contacts (ContactVO) depuis une méthode distante, et nous allons utiliser pour cela un autre design pattern mis en place dans Cairngorm, le ServiceLocator. Ce dernier va nous permettre de gérer nos différents services distants. Dans Flex, le ServiceLocator différe de son implémentation classique car, il est intégré sous forme de composant mxml (de toute façon il sera compilé en AS ).</p>
<pre class="brush: xml">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;Cairngorm:ServiceLocator
	xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot;
	xmlns:Cairngorm=&quot;com.adobe.cairngorm.business.*&quot;&gt;

	&lt;mx:RemoteObject id=&quot;contactService&quot;
		destination=&quot;amfphp&quot;
		source=&quot;ContactService&quot;
		showBusyCursor=&quot;true&quot; /&gt;

&lt;/Cairngorm:ServiceLocator&gt;
</pre>
<p>Dans notre ServiceLocator, on définit ce qu&#8217;on appelle un RemoteObject (qui correspond en faite à la méthode RPC que l&#8217;on va appeler ). L&#8217;id de chaque RemoteObject permet de gérer et d&#8217;appeler plusieurs services au sein du ServiceLocator. Comme son nom l&#8217;indique le <strong>ServiceLocator</strong> va nous permettre de :</p>
<ul>
<li><strong>centraliser la définition des différents services, RPC (Appel de méthode distante &#8211; Remote Procedure Call )</strong></li>
<li><strong>Offrir un accès globalisé à ces services</strong></li>
</ul>
<p>Les plus attentifs ont remarqué, par contre qu&#8217;on n&#8217;a toujours pas spécifié l&#8217;url de notre service. Et bien, qu&#8217;ils se rassurent, c&#8217;est normal puisque cela se fait dans un fichier de configuration (service-config.xml &#8230; cela nous permettra de mieux gérer le déploiement de plusieurs instances de l&#8217;application <del>(oui ca serait plutôt relou de devoir à chaque fois recompiler l&#8217;appli parce qu&#8217;on a mis une appli sur un nouveau serveur )</del> ben pour l&#8217;instant c&#8217;est relou <img src='http://www.lafabrick.com/blog/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /><br />
Par contre pour le coup, je n&#8217;ai pas encore compris toutes les subtilités qu&#8217;offrait ce fichier de config&#8230;mais dans les grandes lignes ça donne ça&#8230; Le services flex transportent les messages, de et vers la destination du service, en utilisant des canaux (message-channel).<br />
Dans notre fichier &#8216;<strong>services-config.xml</strong>&#8216;, il faut donc:</p>
<ul>
<li><strong>définir un service ainsi que sa destination</strong></li>
<li><strong>définir un channel qui sera utilisé par la destination du service</strong></li>
</ul>
<p>Et ça donne&#8230;</p>
<pre class="brush: xml">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;services-config&gt;
	&lt;services&gt;
		&lt;service id=&quot;amfphp-flashremoting-service&quot; class=&quot;flex.messaging.services.RemotingService&quot; messageTypes=&quot;flex.messaging.messages.RemotingMessage&quot;&gt;
			&lt;destination id=&quot;amfphp&quot;&gt;
				&lt;channels&gt;
					&lt;channel ref=&quot;my-amfphp&quot;/&gt;
				&lt;/channels&gt;
				&lt;properties&gt;
					&lt;source&gt;*&lt;/source&gt;
				&lt;/properties&gt;
			&lt;/destination&gt;
		&lt;/service&gt;
	&lt;/services&gt;
	&lt;channels&gt;
		&lt;channel-definition id=&quot;my-amfphp&quot; class=&quot;mx.messaging.channels.AMFChannel&quot;&gt;
			&lt;endpoint uri=&quot;http://flashservices:80/gateway.php&quot; class=&quot;flex.messaging.endpoints.AMFEndpoint&quot;/&gt;
		&lt;/channel-definition&gt;
	&lt;/channels&gt;
&lt;/services-config&gt;
</pre>
<p>Pour les plus motivés, il reste toujours <a hreflang="en" href="http://livedocs.adobe.com/flex/201/html/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Book_Parts&amp;file=ent_services_config_097_04.html">la doc de flex à ce sujet</a><br />
Pour le Flex, je crois qu&#8217;on a fait le tour&#8230; Histoire de tout bien avoir proprement voilà à quoi ca ressemble une fois toutes les classes écrites <img src="/blog/images/Environnement de dev/package.jpg" alt="" /><br />
Maintenant il reste juste la partie php&#8230; juste&#8230;<br />
<strong> Côté serveur </strong>_<br />
Pour commencer, il faut récupérer <a hreflang="en" href="http://www.5etdemi.com/blog/archives/2007/01/AMFPHP-19-beta-2-ridiculously-faster/">AMFPHP 1.9</a> Pour l&#8217;instant c&#8217;est toujours une version béta&#8230; donc à utiliser avec parcimonie. On va modifier un petit paramètre dans le fichier globals.php pour nos besoins de mapping, on va faire pointer le répertoire des VO et celui des services au même endroit.</p>
<pre class="brush: php">
$servicesPath = &quot;services/&quot;;
$voPath = &quot;services/&quot;;
</pre>
<p><strong> Le ContactVO version PHP </strong><br />
Première étape on écrit, non pas la classe ContactService mais la classe <strong>ContactVO</strong> ( parce qu&#8217;il faut bien commencer par quelque part, et puis l&#8217;histoire des poules, des oeufs, des VO etc&#8230; )</p>
<pre class="brush: php">
&lt;?php

	class ContactVO
	{
		var $_explicitType = &quot;vo.ContactVO&quot;;
		var $id;
		var $nom;
		var $prenom;
        var $mail;

	}
?&gt;
</pre>
<p>La classe en php est sensiblement identique, on remarque juste une variable bizarre, $_explicitType qui en fait va nous servir à faire du mapping d&#8217;objet AS / Php.. la grande classe&#8230; Après avoir quelque peu galéré à essayer de mapper les objets&#8230; on est arrivé à établir deux règles pour que tout ca fonctionne.</p>
<ol>
<li>Il faut que le $_explicitType et l&#8217;alias du Remote Class soit identique.</li>
<li>Il faut que l&#8217;identifiant qui va permettre à AMF et Flex de faire le mapping correctement pointe vers la classe de VO en php&#8230;</li>
</ol>
<p>En gros, si notre architecture ressemble à ca&#8230; :<br />
<img src="/blog/images/Environnement de dev/amfphp.jpg" alt="" /><br />
on va spécifier comme chemin &laquo;&nbsp;vo.ContactVO&nbsp;&raquo;<br />
Par contre, si on avait eu ce genre d&#8217;architecture<br />
<img src="/blog/images/Environnement de dev/amfphp2.jpg" alt="" /><br />
nous aurions dû spécifier comme chemin &laquo;&nbsp;com.lafabrick.caringormexemple.vo.ContactVO&nbsp;&raquo; et dans le fichier globals.php on aurait eu :</p>
<pre class="brush: php">
$servicesPath = &quot;../&quot;;
$voPath = &quot;../&quot;;
</pre>
<p>Il aurait fallu déplacer le fichier <em>DiscoveryService.php</em> initialement dans le répertoire services/AMFPHP dans le répertoire racine de AMFPHP, et dans le fichier ServiceLocator, la source aurait été :</p>
<pre class="brush: xml">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;Cairngorm:ServiceLocator
    xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot;
    xmlns:Cairngorm=&quot;com.adobe.cairngorm.business.*&quot;&gt;

       &lt;mx:RemoteObject id=&amp;amp;amp;quot;contactService&amp;amp;amp;quot;
    	     destination=&quot;amfphp&quot;
             source=&quot;com.lafabrick.cairngormexemple.ContactService&quot;
             showBusyCursor=&quot;true&quot; /&gt;
&lt;/Cairngorm:ServiceLocator&gt;;
</pre>
<p><strong> Le ContactService </strong><br />
Comme quoi les histoires de mapping&#8230; TOUT est lié !!! Maintenant passons à lécriture d&#8217;un service simple histoire de tester l&#8217;appel de méthde distante ainsi que le mapping objet&#8230;</p>
<pre class="brush: php">
&lt;?php
include_once &quot;vo/ContactVO.php&quot;;
class ContactService
{
	function loadAll()
	{
		$ar = array();

		$yo = new ContactVO();
		$yo-&gt;id = 1 ;
		$yo-&gt;nom = &quot;Breduillieard&quot;;
		$yo-&gt;prenom = &quot;Lionel&quot;;
		$yo-&gt;mail = &quot;lionel@Breduillieard.com&quot;;
		$ar[] = $yo;

		$erick = new ContactVO();
		$erick-&gt;id = 2 ;
		$erick-&gt;nom = &quot;Ghaumez&quot;;
		$erick-&gt;prenom = &quot;Erick&quot;;
		$erick-&gt;mail = &quot;erick@ghaumez.com&quot;;
		$ar[] = $erick;

		$fab = new ContactVO();
		$fab-&gt;id = 3 ;
		$fab-&gt;nom = &quot;Bizot&quot;;
		$fab-&gt;prenom = &quot;fabien&quot;;
		$fab-&gt;mail = &quot;fabien@bizot.com&quot;;
		$ar[] = $fab;		

 		return  $ar;
	}

}
?&gt;
</pre>
<p>Il est temps de compiler et de déployer&#8230; Et là normalement vous devriez obtenir ça <img src='http://www.lafabrick.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /><br />
<img src=&quot;http://lafabrick.com/blog/images/carnetadresseexemple-20071003-180159.jpg&quot; alt=&quot;&quot; /><br />
Et  vous devriez obtenir ça dans la zone de trace</p>
<pre class="brush: js">
execute command
LoadUsersCommand
result [object ContactVO], [object ContactVO] ,[object ContactVO]
</pre>
<p><a hreflang="fr" href="http://ghaumaldi.univ-lyon2.fr/labs/cairngormexemple/">Voir en ligne</a> &#8211; <a hreflang="fr" href="http://lafabrick.free.fr/labo/cairngormexemple/cairngormexemple.zip">Les sources </a><br />
Merci d&#8217;avoir lu cet article.<br />
Et pour finir quelques liens utiles :</p>
<ul>
<li>Un site de <a hreflang="en" href="http://www.Cairngormdocs.org/">ressources sur Cairngorm</a></li>
<li>Le tutoriel en 6 parties de steven webster sur Cairngorm : <a hreflang="en" href="http://www.adobe.com/devnet/flex/articles/Cairngorm_pt1.html">part 1</a> &#8211; <a hreflang="en" href="http://www.adobe.com/devnet/flex/articles/Cairngorm_pt2.html">part 2</a> &#8211; <a hreflang="en" href="http://www.adobe.com/devnet/flex/articles/Cairngorm_pt3.html">part 3</a> &#8211; <a hreflang="en" href="http://www.adobe.com/devnet/flex/articles/Cairngorm_pt4.html">part 4</a> &#8211; <a hreflang="en" href="http://www.adobe.com/devnet/flex/articles/Cairngorm_pt5.html">part 5</a> &#8211; <a hreflang="en" href="http://www.adobe.com/devnet/flex/articles/Cairngorm_pt6.html">part 6</a></li>
<li><a hreflang="en" href="http://livedocs.adobe.com/flex/201/html/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Book_Parts&amp;file=ent_services_config_097_04.html">Configuring data service</a></li>
<li><a hreflang="en" href="http://java.sun.com/j2ee/patterns/">Les patterns J2EE</a></li>
</ul>
<p>Autres articles sur le même sujet
<ul>
<li><a href="http://www.lafabrick.com/blog/2008/02/04/299-un-projet-java-flex-avec-maven-2/" rel="bookmark" title="4 février 2008">Un projet Java / Flex avec Maven 2</a></li>
<li><a href="http://www.lafabrick.com/blog/2008/01/10/288-cairngorm-pour-les-fainants-tour-d-horizons-des-code-generator/" rel="bookmark" title="10 janvier 2008">Cairngorm pour les fainéants&#8230; Tour d&#8217;horizons des code generator</a></li>
<li><a href="http://www.lafabrick.com/blog/2009/01/13/786-reflex-1-une-micro-architecture-pour-flex-simple/" rel="bookmark" title="13 janvier 2009">Reflex #1: une micro-architecture pour Flex&#8230; simple !</a></li>
<li><a href="http://www.lafabrick.com/blog/2009/01/15/819-reflex-2-vous-reprendez-bien-un-peu-de-ioc/" rel="bookmark" title="15 janvier 2009">Reflex #2 : vous reprendrez bien un peu de IOC ?</a></li>
</ul>
<p><!-- Similar Posts took 18.273 ms --></p>
]]></content:encoded>
			<wfw:commentRss>http://www.lafabrick.com/blog/2007/10/03/256-titre/feed/</wfw:commentRss>
		<slash:comments>41</slash:comments>
		</item>
	</channel>
</rss>

