Catégorie : Programmation     Tags :      

    Retrouvez cet article dans : Linux Magazine 88

    Lors du précédent article, nous avons montré comment les fonctionnalités de base de Seaside permettent de créer des applications dynamiques pour le web. Nous avons notamment abordé la génération contrôlée de code XHTML directement à partir de Smalltalk, ainsi que les mécanismes de création d’ancres et de call-backs pour faire des formulaires. Dans cet article, nous allons aborder le mécanisme sous-jacent à Seaside nommé « Call/Answer » qui permet de composer des flots de contrôle complexes avec les widgets, réutilisables dans d’autres contextes, puis nous ferons un tour des outils de développement disponibles. Afin de reproduire les exemples de cette présentation, nous vous invitons à utiliser la distribution préconstruite la plus récente disponible sur le site de Seaside (http://www.seaside.st/). Téléchargez la version 2.6 du 3 septembre 2006.

    Un magasin en ligne

    Pour illustrer les concepts fondamentaux de Seaside, nous utilisons l’application « magasin en ligne de Sushi » qui est fournie dans la distribution téléchargeable.
    Pour y accéder, lancez le serveur web en exécutant WAKom startOn: 8080 dans un espace de travail Squeak (workspace), puis dirigez votre navigateur web sur l’adresse : http://localhost:8080/seaside/examples/store.
    Cette application simule un magasin de vente de sushis en ligne. Comme vous allez le constater, ce magasin est constitué d’un certain nombre de composants de base (voir la figure 1) comme : la liste des sushis, l’affichage d’un sushi spécifique, le panier, le formulaire de carte de crédit, etc.

     

    /img-articles/lm/88/art-10/fig-1.jpg

    Figure 1 : Photo d’écran de l’application « Magasin en ligne de vente de sushis »

    Ce sont potentiellement des composants réutilisables dans d’autres applications.
    Ce magasin dispose du flot de contrôle suivant (voir la figure 2) : le client peut remplir son panier, puis décider de payer, mais lorsqu’il décide de payer, il peut néanmoins revenir en arrière afin de continuer d’acheter. Une fois qu’il a fini d’acheter, le client doit donner une adresse à laquelle ses sushis seront envoyés. Il peut également donner une adresse différente à laquelle sera envoyée la facture. Finalement, il remplit ses informations bancaires.

     

    /img-articles/lm/88/art-10/fig-2.jpg

    Figure 2 : Le flot de contrôle suivi par le client

     

    Clairement, le flot de cette application n’est pas juste une suite de pages affichées séquentiellement les unes à la suite des autres.
    Il est aussi important de voir que l’on aimerait pouvoir réutiliser certains composants comme l’édition des informations bancaires, ainsi que le flot correspondant dans d’autres applications que celle-ci.

    En Seaside, le flot complet d’un magasin peut être implémenté de différentes façons. Dans la version que nous avons téléchargée, on utilise la classe StoreTask qui hérite de la classe WATask. Une WATask est un composant non visuel qui souvent définit le flot d’une application. La méthode go implémente le flot du composant. La méthode suivante montre qu’avec Seaside le flot de l’application est implémenté directement en Smalltalk en utilisant les constructeurs traditionnels du langage comme les boucles conditionnelles et les conditions.
    La méthode tout d’abord crée un panier, instance de la classe WAStoreCart, et la stocke dans la variable d’instance cart. Ensuite, la méthode fillCart, qui permet à l’utilisateur de remplir son panier, est exécutée, et ce, tant que la confirmation d’arrêt n’est pas passée. Enfin, une adresse d’envoi est demandée à l’utilisateur.

    StoreTask>>go
     | shipping billing creditCard |
     cart := WAStoreCart new.
     [ self fillCart.
     self confirmContentsOfCart ] whileFalse.
     shipping := self getShippingAddress.
     billing := (self useAsBillingAddress: shipping)
    			ifFalse: [ self getBillingAddress ]
     			ifTrue: [ shipping ].
     creditCard := self getPaymentInfo.
     self shipTo: shipping billTo: billing payWith: creditCard.

    La méthode useAsBillingAddress: présente un dialogue très simple où l’on demande à l’utilisateur s’il veut utiliser son adresse d’envoi comme adresse de facturation.

    StoreTask>>useAsBillingAddress: anAddress
      ^ self confirm: ‘Do you wish to use ‘, anAddress street printString, ‘ as your billing address?’

    En revanche, d’autres fonctionnalités impliquent de créer de nouveaux composants et de leur passer le contrôle de l’application. C’est le cas de getShippingAddress dont voici le code :

    getShippingAddress
      ^ self getAddressWithMessage: ‘Please enter your shipping address:’.

    On demande à l’utilisateur de bien vouloir entrer son adresse d’envoi. Comme d’habitude, on a un code Smalltalk qui se lit très facilement.
    Ceci montre clairement que le flot de contrôle de l’application est exprimé à l’aide d’abstractions de haut niveau et illustre comment les informations passent entre les composants de l’application.
    Par exemple, ici, l’adresse est créée par la méthode getShippingAddress, stockée dans une variable, puis passée naturellement comme argument à la méthode useAsBillingAddress:.
    Ici, bien que l’application soit composée de plusieurs pages visibles éventuellement dans différents navigateurs, il n’y a pas besoin de sérialiser l’objet adress ou de faire d’autres manipulations comme celles que l’on effectue généralement dans les frameworks similaires. On passe simplement l’objet comme n’importe quel objet sans se soucier de l’existence du protocole web HTTP sous-jacent. La souplesse de Seaside, couplée au pouvoir d’expression de Smalltalk permet ainsi de déboguer des applications au vol et ceci dynamiquement comme toutes les autres applications.

    Passage du flot de contrôle entre composants

    Nous allons détailler le mécanisme essentiel de Call/Answer (Appel/Réponse), qui permet de passer le contrôle d’un composant à un autre. Ce mécanisme Call/Answer permet de réintroduire élégamment le retour de procédure ou d’appel de méthodes et ainsi d’éviter d’avoir des mécanismes proches du GOTO comme on en retrouve dans la plupart des frameworks web.
    L’utilisation de mécanismes de type GOTO est en fait lié au protocole HTTP. Seaside permet de s’abstraire de ce problème. Pour preuve, Avi Bryant, le créateur de Seaside a écrit un article « HTTP considered harmful » par référence au papier « Goto statement considered harmful » d’Edsger W. Dijkstra, un des pères de la programmation structurée. Seaside permet donc de construire des applications structurées pour le web.

    /img-articles/lm/88/art-10/fig-3.jpg

    Figure 3 : Le mécanisme Call/Answer à l’œuvre

     La figure 3 illustre en détail le fonctionnement de ce mécanisme. Lorsqu’une méthode m1 d’un composant A invoque la méthode call: avec une instance d’un autre composant, ce dernier prend la place de A et son flot de contrôle est activé.
    Si lors du déroulement de ce flot, ce composant invoque la méthode answer: avec un argument, le composant B disparaît et le composant A reprend son exécution là où il avait invoqué le composant B et le résultat du call: est l’objet qui a été passé en argument lors de l’invocation de la méthode answer:.
    En fait, on reproduit l’exécution d’une fonction ou d’une routine qui, à la fin de son exécution, rend le contrôle à son appelant.
    Examinons un exemple concret dans le code du magasin. Si l’on regarde la définition de la méthode getAddressWithMessage: de la classe StoreTask, voici ce que nous avons :

    StoreTask>>getAddressWithMessage: aString
       ^ self call: (WAStoreAddressEditor new
    			validateWith: [:a | a validate];
    			addMessage: aString;
    			yourself)

    Cette méthode rend le résultat d’un appel à call: en passant en paramètre une instance de l’éditeur d’adresses qui est paramétré pour valider la chaîne que l’utilisateur rentrera. Lorsque l’application principale invoque cette méthode, l’éditeur d’adresses s’exécute. Si vous regardez le code de la classe WAStoreAddressEditor, vous trouverez que la méthode ok, dont le code est présenté ci-après, utilise la méthode answer: avec une adresse.

    WAStoreAddressEditor>>ok
          self answer: address

    Cela a pour conséquence de fermer le composant courant, ici donc l’éditeur d’adresses, et de redonner la main à l’instance de WAStoreTask au sein de la méthode getAddressWithMessage: qui va donc juste retourner l’objet adress au flot de la méthode go que nous avons vue précédemment.
    Une application est souvent composée de plusieurs composants présents en même temps à l’écran sur la même page. Ces composants ont leur propre flot de contrôle et peuvent évoluer en parallèle indépendamment les uns des autres.
    Par exemple, voici le code de rendu de la classe WAStoreFillCart qui dispose les composants de l’application. L’utilisateur peut interagir librement avec chaque sous-composant qui va exécuter son propre flot et éventuellement créer d’autres composants en utilisant le mécanisme Call/Answer.

    WAStoreFillCart>>renderContentOn: html
       html table: [
            html tableRow: [
    	htmll cssId: ‘nav’; tableData: [ self renderNavBarOn: html ].
    	html cssId: ‘main’; tableData: main.
    	html cssId: ‘side’; tableData: cartView. ]]

    La figure suivante montre comment un utilisateur interagit avec deux composants coexistants (la liste des sushis et le panier) sur la même page. Le code pour construire cette page est similaire à celui présenté précédemment (voir figure 4).

    Isolate:, contrôler l’accès à l’historique

    Lors du développement d’applications web, il est souhaitable de pouvoir contrôler les retours en arrière afin que l’utilisateur ne puisse pas, par exemple, acheter un article, payer puis revenir en arrière et prendre plus d’articles.

    /img-articles/lm/88/art-10/fig-4.jpg

    Figure 4 : Deux composants avec lesquels on interagit en parallèle

    Seaside offre la possibilité de bloquer la navigation dans un certain contexte. Pour cela, il suffit d’exécuter le code comme argument d’un message isolate:. Le code suivant montre le véritable code de la méthode go. On observe que l’utilisateur peut choisir des sushis, décider de payer, puis revenir en arrière librement, mais une fois qu’il a décidé de payer, il ne peut plus revenir en arrière. Une fois le whileFalse terminé, l’utilisateur ne pourra plus que passer dans un autre contexte à savoir celui de donner ses informations.

    StoreTask>>go
      | shipping billing creditCard |
      cart := WAStoreCart new.
      self isolate: [[self fillCart.
    		   self confirmContentsOfCart] whileFalse].
      self isolate: [shipping := self getShippingAddress.
      billing := (self useAsBillingAddress: shipping) 	ifFalse: [self getBillingAddress] 		ifTrue: [shipping].
      creditCard := self getPaymentInfo.
      self shipTo: shipping billTo: billing payWith: creditCard].

    0utils de développement

    Seaside par l’intermédiaire de son interface web procure un certain nombre d’outils facilitant la vie du développeur. En bas de chaque page Seaside, il y a une barre de liens (voir figure 5) permettant de lancer une nouvelle session, de configurer l’application (notamment lui associer une URL), d’activer le mécanisme de halos autour des composants, de profiler les performances de votre application et, enfin, de valider le code XHTML de votre application.
    Cliquons sur le lien ‘Toggle halos’ pendant que notre application de vente de Sushis s’exécute : comme on peut voir sur la figure 5, chaque composant de la page apparaît de manière claire et visuelle, entouré de son nom et d’un ensemble d’outils : c’est le halo d’un composant. Ce halo permet d’une part de visualiser la structure d’emboîtement de l’application et, d’autre part, d’agir séparément sur chaque composant, et ceci, pendant que l’application s’exécute.
    Si on clique sur la clé à molette du halo, un navigateur de classe (version simplifiée du System Browser de Smalltalk) sur la classe du composant apparaît. Ce navigateur permet de visualiser et/ou de modifier les méthodes de ce composant, puis d’observer le résultat de cette modification sur l’exécution du composant. L’œil, quant à lui, permet d’avoir un inspecteur sur l’instance du composant et, enfin, le crayon permet de modifier la feuille de style CSS de ce composant.
    Les deux liens R et S à droite du halo d’un composant permettent respectivement d’avoir accès au rendu (R) et au code source (S) XHTML de chaque composant. On remarquera que le code source XHTML se modifie dynamiquement pendant l’exécution de l’application. Un deuxième clic sur le lien ‘Toggle halos’ permet de revenir à une application où les halos ont disparu.
    La barre Seaside peut être enlevée lors du déploiement d’une application web.
    Cette interface de développement a elle-même été développée en Seaside et utilise les mécanismes Call/Answer afin de remplacer de manière temporaire vos composants par les outils de développement web de Seaside.
    Nous vous conseillons d’utiliser le navigateur Firefox pour tous vos développements avec Seaside. Vous pouvez coupler avec profit l’utilisation de Firefox avec le plugin FireBug (http://www.joehewitt.com/software/firebug/) qui permet de voir de manière agréable le code XHTML de chaque page et de tracer les interactions entre le navigateur et votre application. Ce plugin peut s’avérer indispensable dans le cadre d’une application complexe.

    /img-articles/lm/88/art-10/fig-5.jpg

     Figure 5 : L’interface utilisateur de Seaside

    L’interface utilisateur web n’est pas le seul moyen de développer et de déboguer une application Seaside. En pratique, on réutilise au maximum les outils fournis par Smalltalk : inspecteur, navigateur de classes, débogueur que nous avons déjà vus dans les articles précédents.
    La figure 6 illustre un exemple que l’on rencontre fréquemment lors de développements d’applications Seaside. Une erreur se déclenche lors de l’utilisation d’une application (a). Il s’agit ici d’un message envoyé à un objet qui ne le comprend pas (Message Not Understood). La pile d’exécution Smalltalk apparaît dans le navigateur web. Si on clique sur le bouton « debug » en haut de la page, un débogueur s’ouvre dans l’image Squeak (b). On corrige l’erreur (c), on recompile la méthode (ALT-s) et on relance l’application en appuyant sur le bouton « proceed ». Automatiquement, le navigateur web continue l’exécution de l’application à l’emplacement où s’est déroulée l’erreur (d). Notez que le serveur n’a été stoppé à aucun moment. De plus, le programmeur peut voir directement son erreur sans devoir faire de print dans son code. Il peut fixer au vol ses bugs et continue l’application comme si rien ne s’était passé. On voit clairement le gain en temps de développement procuré par Smalltalk et Seaside.

    /img-articles/lm/88/art-10/fig-6.jpg

     Figure 6 : Interaction entre les outils de débogage de Smalltalk et l’interface web de Seaside

    En conclusion

    Seaside est un framework web extrêmement puissant. Cette puissance alliée à la recompilation incrémentale et aux outils de Smalltalk permet de déboguer et de changer au vol les applications web qui tourneraient sur votre serveur, et ceci, sans avoir besoin de relancer celui-ci.
    Faute de place, nous n’avons abordé ici que les concepts de base de Seaside. Ces concepts seront suffisants pour appréhender Seaside dans sa totalité. Pour vous familiariser avec ce framework innovant, essayez de modifier l’exemple du magasin en ligne.
    Dans la très accueillante mailing-list Seaside, la question de l’hébergement d’applications Seaside est soulevée. Les professionnels préféreront administrer leur propre hébergement distant et accéder à Squeak via VNC. Pour ceux que l’expérience tente, un service d’hébergement d’applications est disponible depuis peu sur
    http://www.seasidehosting.st/.
    Ce service est totalement gratuit pour des applications non commerciales, car sponsorisé par la société Netstyle.ch, spécialiste du développement Seaside et l’association européenne des utilisateurs de Smalltalk, http://www.esug.org/.
    Seaside est en plein développement, de nombreuses fonctionnalités sont rajoutées régulièrement : support d’AJAX et du Web 2.0 (http://scriptaculous.seasidehosting.st/) sans avoir besoin d’écrire du code JavaScript, intégration avec des bases de données (Magma), librairies de composants réutilisables (ShoreComponents), le système de contenu (CMS) Pier. Le mieux pour suivre l’actualité de Seaside est de s’abonner à la liste de diffusion. Il n’y a pas de liste francophone, mais les questions concernant Seaside peuvent être posées sur la liste de diffusion squeak-fr : http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/squeak-fr.
    Vous pouvez également participer à la prochaine Smalltalk Party à Paris où des démonstrations de Seaside seront organisées.

    Smalltalk Party Paris 2006 

    Pour la 5ème année consécutive, le groupe des utilisateurs francophones de Smalltalk (French Smalltalk User Group) organise une Smalltalk Party le samedi 25 novembre prochain à Paris. Il s’agit d’une manifestation libre d’accès et informelle regroupant des utilisateurs du langage à objets dynamique Smalltalk. Cette journée, soutenue par le groupe européen des utilisateurs de Smalltalk réunit habituellement des personnes d’origines très diverses : des industriels, des créateurs multimédias, des enseignants, des étudiants, des chercheurs, ainsi que des curieux qui veulent découvrir Smalltalk.
    Différentes démonstrations et discussions sont au programme (initiations, applications web, Smalltalk en entreprise, applications pédagogiques...). Pour rappel, Smalltalk est un langage à objets simple (la syntaxe tient sur 1 page, tout est objet), multiplateforme (à base de machine virtuelle) tout en étant très puissant (dynamicité, réflexion). Il est utilisé industriellement (AMD, UPS, MMA...), ainsi que dans les universités et dans les laboratoires de recherche.
    Différents environnements Smalltalk commerciaux ou libres existent. C’est le cas notamment de Squeak (licence APSL 2.0) qui inclut une interface de programmation visuelle.  Il y aura notamment des démonstrations des EToys (l’interface de programmation visuelle pour les enfants), de Seaside (le framework web basé sur les continuations), de Croquet (Environnement virtuel 3D P2P), ainsi que des prototypes de recherche. Un Dojo XP (eXtreme Programming) de programmation sera organisé en collaboration avec la communauté XP francophone.
    Détails et inscription sur le wiki :
    http://community.ofset.org/wiki/Smalltalk_Party_Paris_2006

    Retrouvez cet article dans : Linux Magazine 88

    Posté par (La rédaction) | Signature : Stephane Ducasse, Serge Stinckwich | Article paru dans

    Laissez une réponse

    Vous devez avoir ouvert une session pour écrire un commentaire.


    • Il y a actuellement

    • 709 articles/billets en ligne.