May 2010 - Messages

Démonstration Agile
20 May 10 03:58 AM | Nico | avec no comments

Nous sommes dans une Société de Services, une structure spécialisée sur des projets e-Business, qui réalise des projets au forfait.

Il est 14h30, nous avons rendez-vous avec un Architecte/Développeur senior, qui connait la plate-forme .Net mais ne connait pas nos outils. Notre objectif est de réaliser un petit démonstrateur sur un exemple simple d'application.

Le premier objectif est d'installer le produit, à l'aide de notre setup. Pendant ce temps, nous résumons les objectifs de notre approche:

  • Maitriser la complexité en proposant une approche descriptive plutôt qu'impérative; configurer le maximum de choses et écrire le minimum de code.
  • Etre en état de fonctionnement le 1er jour, et avoir en permanence une application en état de marche.
  • Avoir une progression linéaire qui permet ajout et modification au fur et à mesure de l'avancement avec le minimum d'impact de l'existant.

Nous expliquons brièvement comment nous atteignons ces objectifs:

  • En définissant un modèle relationnel de données, qui permet une gestion dynamique des types, les échanges techniques sont écrits d'avance.
  • En séparant très nettement couche métier et couche technique, notre RunTime permet l'execution dynamique du code technique, on évite d'écrire du code technique, répétitif, ennuyeux, et source d'erreurs.
  • En s'appuyant sur le principe de Hollywood ("Don't call us, we call you"), on évite d'écrire du code d'appel, qui est source de rigidité.

 

Nous présentons ensuite notre vision de l'Architecture Web, qui est assez différente de ce que les Architectes ont l'habitude de voir, et qui permet une fluidité native tout à fait impressionnante:

  • Le HTML affiché est produit dans le navigateur uniquement, et en aucun cas sur le serveur, ce qui permet une customisation totale avec des CSS standard.
  • Il n'y a que des données qui sont échangées entre client et serveur:
    • Les données échangées sont uniquement des données métiers. Mais elles ne sont pas typées au sens métier; on n'échange pas des Produits ou des Factures entre le client et le server, mais on échange des Identifiants (Guid), des String, des Int, des Date, ou des DataSet, conteneur générique de Données Métiers.
    • D'un point de vue technique, on privilégie le format de celui qui reçoit.
      • au format JSON en provenance du serveur
      • au format XML en provenance du client
    • Tous les transtypages et conversion sont natifs, aucun code n'est nécessaire, et les échanges sont totalement transparents pour le développeur.
  • L'état de l'application est maintenu dans le navigateur, et tous les traitements serveurs sont Stateless
  • Les échanges entre le client et le serveur sont totalement maitrisés par le développeur; c'est lui qui décide quand il doit descendre des données du Serveur ou remonter des données depuis le client. Il n'y a aucun aller et retour à l'insu du développeur.

 

Nous présentons ensuite l'environnement de Développement:

  • Visual Studio pour écrire le code:
    • la description du modèle métier à l'aide de notre DSL, qui permet d'importer les structures depuis une base existante.
    • des Controles HTML, qui décrivent les éléments de l'IHM; ce sont des Template vide, l'injection des données se fera dans le navigateur, à partir de la configuration.
    • des Commandes Client, en Javascript (validateurs ou calculs) ou Serveur, en C# ou VB.Net (essentiellement pour la lecture des Données).
    • du CSS pour le design

 

  • BindingStudio pour décrire:
    • Les liens entre les Contrôles et les Données (DataBinding)
    • Les liens entre les Contrôles et les Traitements (CommandBinding)
    • Les liens entre les Contrôles et les Contrôles (LayoutBinding)
    • Le StyleBinding, qui permet de réaliser des liens dynamiques entre class CSS et élément de l'IHM (très utile pour faire des affichages dynamiques en fonction des données).

 

Nous décrivons également l'environnement de Production, qui est constitué d'un répertoire, contenant toutes les ressources de l'Application. D'un point de vue du disque, l'organisation est la suivante:

 

Il est 16h, nous pouvons démarrer notre projet. Il s'agit d'afficher quelques formulaires sur une Base exemple d'un outil CRM.

 

Nous créons :

  • un projet Visual Studio, et une Application dans BindingStudio.
  • un EntityDesigner dans Visual Studio.
  • un Service de Données et un DataSet logique dans l'Application. 

 

Ces opérations constituent en quelque sorte l'itération 0, qui permet de démarrer le projet, faire la configuration minimale pour ensuite démarrer des cycles de développement.

 

Il est 16h15, le 1er cycle de développement peut commencer:

 

1/ Nous importons 3 tables de la base pour constituer le modèle initial. Nous en profitons pour décrire les principales propriétés de nos entités/relations.

 



2/ Nous écrivons la commande de lecture des données. Nous commençons simplement avec la lecture d'une table en base, ce qui s'écrit simplement avec 3 lignes de code.

 

 

3/ Nous écrivons un premier contrôle qui contient uniquement un bouton et une grille.

 

 

4/ Les liens sont configurés dans BindingStudio.

  • Nous créons une vue de démarrage sur le contrôle créé.
  • Nous configurons l'appel de la commande de chargement sur le click du bouton.
  • Nous configurons la grille pour afficher les données.

 

 

5/ Nous testons notre application. Il est 16h50 ! 

 

 

A ce stade, il est important de comprendre et de mesurer concrètement ce que nous avons fait car nous avons passé l'essentiel de notre temps à parler, le temps de réalisation proprement dit, est de quelques minutes :

  • Nous avons écrit 3 lignes de C#
  • Nous avons écrit 3 lignes de HTML
  • Nous avons effectué 10 clics de souris dans BindingStudio

 

Les 10 clics ont une valeur essentielle pour l'application, mais ne constituent pas de poids dans le développement. Ils sont répétables, modifiables, à l'infini, avec le minimum d'impact. Si on avait écrit 100 lignes de code à la place, non seulement, cela aurait pris plus de temps, mais cela aurait surtout constitué un actif pesant à maintenir pour la suite de l'application. Et c'est parce que nous avons écrit un minimum de code, que l'on va pouvoir évoluer facilement avec l'existant.

 

Bien sûr, le résultat est encore loin d'être abouti, nous voudrons certainement mettre un menu plus tard, et organiser l'affichage différemment, mais nous sommes déjà dans un développement itératif et nous pouvons recommencer notre cycle, en incrémentant notre application; nous souhaitons ajouter une 2ème grille avec les données Child de la table Société.

 

1/ Notre Entité child est déjà présente, le schéma n'est pas modifié.

 

2/ Notre chargement doit ajouter une ligne pour tenir compte du chargement des Entités Child. Nous souhaitons faire un Chargement Lazy, et nous écrivons une 2ème Commande qui charge les Entités Sociétés à partir de l'identifiant d'un Groupe Parent.

 

 

3/ Nous ajoutons un 2ème contrôle qui comporte également une grille. Nous ajoutons un Contrôle Conteneur avec 2 panels pour afficher les 2 vues, ainsi qu'un bouton supplémentaire pour charger les Sociétés. 

 

 

 

Nous ajoutons le CSS adequat pour afficher les Panels l'un à côté de l'autre.

 

 

 

Vu que le HTML est uniquement produit sur le client, tout le design est réalisé avec du CSS standard.

 

4/ Nous créons une 2ème vue et configurons la 2ème grille, à l'aide d'un Binding Relationnel. Nous créons la vue conteneur et configurons le Layout, ainsi que l'appel de la commande lazy pour le chargement des entités Child. Là encore, ce sont 10 clics supplémentaires dans Binding Studio, sans aucune considération technique.

 

5/ Nous testons notre application. Il est 17h !

 

 

 

Le Binding relationnel fonctionne, avec une fluidité étonnante, et nous n'avons pas écrit une seule ligne de code pour le faire fonctionner. De plus, nous avons réalisé notre cycle de façon extrêmement facilement, sans aucun impact sur l'existant.

 

Continuons, et enrichissons notre application: nous voulons maintenant éditer et sauvegarder nos données, ainsi que modifier l'apparence, en ajoutant une barre d'outil, et la possibilité d'accéder aux Contacts.

 

1/ Aucun ajout n'est nécessaire au schéma dans cette itération.

 

2/ Nous ajoutons une commande de chargement des Contacts, toujours en LazyLoading, exactement de la même manière que pour les Sociétés:

 

 

3/ Nous avons besoin d'enrichir les contrôles existant:

  • Ajout d'un Panel sur le vue principale qui va contenir la barre d'outils
  • Ajout d'un contrôle pour la barre d'outils, dans lequel on met les différents boutons.
  • Ajout d'1 controle d'édition de Contact
  • ainsi que de modifier le CSS pour positionner nos éléments.

 

4/ Nous configurons.

  • 1 nouvelles vues sur la barre d'outils
  • 1 LayoutBinding sur la vue principale
  • 2 nouveaux DataBinding pour l'édition
  • 1 CommandBidning pour la sauvegarde; aucune commande serveur n'est à écrire, toute la gestion de la sauvegarde est dynamiquement faite à partir du Modèle (Create, Update, Delete).

 

5/ Nous testons notre application, il est 17h15 !

 

 

Ah, et puis non, en fait, nous voulons un arbre et des onglets à la place du Layout que l'on a fait. Rien de plus simple, le HTML est extrêmement simple et la configuration immédiate à réaliser. Quelques minutes et quelques clics plus tard, nous avons une nouvelle interface, et le code n'a pas changé !

 

 

Voilà, c'est exactement l'objectif que l'on souhaite atteindre; on fait des choses simples, on teste, et on valide que c'est bien ce que l'on veut, à partir de l'application fonctionnelle. Nos cycles de développement sont courts, on va à l'essentiel, ce sont les demandes de fonctionnalités métier qui pilotent les cycles de développement, et qui sont visible immédiatement.

 

En à peine 3 heures, nous avons atteint notre objectif d'avoir un premier morceau d'application qui fonctionne, en partant de zéro ! Notre application est pour l'instant minimaliste, notre interlocuteur est encore loin d'être autonome, mais nous avons pu amorcer un cycle de développement extrêmement agile, en optimisant le ratio entre le code écrit et la valeur du produit, et surtout, en garantissant une application qui fonctionne dès le premier jour. L'itération 0 n'a pris que quelques minutes et la progression est linéaire, parce que les éléments sont indépendants les uns des autres.

 

Non seulement l'application fonctionne, mais elle est prête à déployée; la simple copie d'un répertoire suffit à la mettre en production.

 

Bien sur, la conception ne va pas tomber du ciel, le modèle doit être pensé et conçu, l'IHM doit être définie, mais ce sont des considérations métier dont il est question, et leur mise en œuvre ne va pas être un frein aux développements futurs, et pourra être ajustée au fur et à mesure. Nous sommes dans un contexte de flux continu de changements.

 

Et la configuration s'apprend vite, les automatismes viennent relativement vite. On prend vite goût à ne plus écrire du code rébarbatif, pour éditer des données dans un formulaire. Nous avons vu l'essentiel des opérations de base. Il y a bien sur tout un tas de trucs et astuces, pour aller plus loin, et construire une véritable application métier, sécurisée, avec toutes les contraintes d'un Système d'Informations d'entreprise. Cela se fait toujours avec le même esprit, en écrivant le minimum de code.

 

C'est parce qu'il y a peu de code, qu'il y a peu de problèmes, et que la maintenance et l'adaptation aux changements est possible.

Classé sous : , , , ,
Premier projet Web, ça marche !
03 May 10 01:46 PM | Nico | avec no comments

Nous sortons de quelques semaines intenses où nous avons accompagnés un nouveau client, un éditeur de logiciel  qui souhaite développer un nouveau produit avec notre technologie.

L'équipe de développement est composé de 3 personnes experts sur leur domaine métier ; ils n'ont pas d'expériences dans les technologies Microsoft, ils ont précédemment travaillé avec un AGL propriétaire et en PHP/ Flash pour quelques projets. C'est donc, en partant de zéro sur l'univers Microsoft que nous avons accompagné l'équipe dans le développement de son application avec notre approche et nos outils.

Nous avons dispensé 8 jours de formation: 5 jours sur la plate-forme .Net, et 3 jours sur Aspectize. Avec le recul, sans doute 1 ou 2 jours supplémentaires n'auraient pas été inutiles sur la plate-forme Aspectize. Notre solution est suffisamment riche en fonctionnalités et son originalité méritent bien un cursus de 5 jours. Certains concepts méritent d'être répétés, et détaillés sur des exemples simples pour bien les utiliser dans le projet.

Deux exemples en particulier:

  • La logique des échanges entre client et server est totalement nouvelle, et n'a pas d'équivalent dans une architecture web classique. L'état, matérialisé par les données, est maintenu côté client dans le navigateur, et seules les données sont échangées entre client et serveur. Cette logique a un impact sur le fonctionnement de l'application, et permet d'obtenir un comportement et une fluidité qu'il était très difficile, voire impossible, d'obtenir auparavant. Elle ouvre de nouvelles perspectives applicatives, et évitent certains écueils classiques (comme la perte des données d'un formulaire en cours de saisie par exemple). Néanmoins, il est important de bien comprendre cette logique pour en tirer partie, et éviter des allers & retours inutiles et couteux entre le client et le serveur.
  • La logique déclarative du binding relationnel, a un pouvoir expressif très puissant pour décrire le fonctionnement de l'IHM. Le "DataName" associé à des contrôles est simple à définir (1 clic de souris suffit), et permet d'afficher les données filtrées et synchronisées entre plusieurs formulaires. Comme tout ce qui est nouveau, ce n'est pas toujours immédiat et il y a quelques bonnes pratiques à mettre en œuvre pour configurer correctement.

Evidemment, ce projet est aussi pour nous, une mise à l'eau de notre produit, dans un environnement autre que le notre. Cela permet évidemment de déceler et corriger certains dysfonctionnements (l'intégration avec le contrôleur de source ou certains bugs de notre moteur javascript), et en même temps d'intégrer des bonnes idées de fonctionnalités pour  augmenter le confort du développeur. Nous avons pu ainsi apporter des nouveautés comme une meilleure gestion du Layout, pour obtenir un rendu plus rapidement, et des nouveaux contrôles bindable (DateTimePicker, CheckBoxList).

Alors, qu'est ce que nous pouvons tirer comme conclusion de cette première expérience d'un projet Web ?

Comme cette appréciation pourrait être sujette à interprétation subjective, nous avons mesuré quelques critères significatifs.

La charge de travail est de 70 jours répartis entre les 3 développeurs.

Le Schéma est constitué de 47 entités (38 Entités et 9 Enum) et 86 relations ! Cela peut sembler étrange, mais l'importance des relations est fondamentale dans la logique fonctionnelle de l'application. C'est dans la définition même de ces relations que sont définies une grande partie des règles de gestion de l'Application. Là où un code fastidieux aurait été nécessaire, le schéma permet de modéliser l'essentiel, de façon déclarative et graphique. Au niveau physique, la base SQL Server contient 53 tables (ce qui donne une idée de l'importance du projet).

L'interface utilisateur comprends 225 vues configurées. Chaque vue configurée est un UserControl, qui constitue un morceau de page Web, qui sont imbriquées les unes dans les autres. Au sein de ces UserControl, il y a 629 Contrôles configurés (TextBox, CheckBox, Button, Grille, Arbre ...) ce qui correspond à 862 DataBinding (pour l'affichage/édition de données), et 578 CommandBinding (pour l'appel d'un Service). Il faut bien comprendre qu'un Binding se fait en quelques secondes (2 ou 3 clics de souris, aucune saisie d'information clavier), là où l'équivalent en code classique nécessiterait des heures de développement et de tests.

Et justement, le code écrit - car il y en a - que représente t il ?

  • 1 240 lignes de C#
  • 735 lignes de JavaScript
  • 1 294 lignes de CSS (les développeurs maitrisent le CSS, et ont fait un travail très soigné sur le design de l'application)

Ce volume de code est extrêmement faible compte tenu de la richesse et de la complexité de l'application (c'est le nombre de lignes tel qu'il apparait dans l'IDE Visual Studio, c'est à dire qu'il inclut les lignes blanches, les { }, les using et autres verbosité du code, et donc que le nombre de ligne réellement utile qui a nécessité des neurones de développeur est évidemment beaucoup moins). Et bien sur, 0 lignes de SQL, 0 lignes de code technique, pas de manipulation de contrôles, pas d'abonnement, pas de code de gestion d'erreurs, pas de code de gestion de la sécurité, pas de manipulation de DOM ou autre considération technique ! L'ensemble du code est essentiellement le chargement des données, et quelques règles métiers (transformations de données, validation); c'est un code simplelisible, qui manipule les données du Schéma, a très peu d'imbrications, et est directement lié avec le fonctionnel de l'application.

Juste pour voir, s'il y a un développement .Net d'un projet comparable pas loin de vous, combien y a-t-il de lignes de code ? vous serez surpris de l'étendu du score, et vous comprendrez mieux pourquoi cela prend autant de temps et pourquoi il y a autant de problèmes.

Et il s'agit d'un progiciel, d'une application métiersécuriséemultilinguefull-ajax, destinée à être utilisée chez des Grands Comptes, avec toutes les contraintes d'un Système d'Informations d'entreprise ! Evidemment, tout n'est pas fini à l'heure actuelle, mais l'application fonctionne en permanence, et les nouveaux Use Case sont implémentés tous les jours.

Enfin, au delà du volume de code, il y a notre appréciation personnelle, qui n'est pas mesurable, mais qui a réellement fonctionné, à savoir l'agilité colossale du projet. On modélise, on configure, on constate, on ajuste; le cycle de développement d'une heure est une réalité. Cela permet une agilité étonnante, sans doute jamais atteinte dans un développement spécifique. A plusieurs reprises, des changements de modèles ont eu lieu; s'ils sont structurants sur le plan fonctionnel, ils ne le sont pas au niveau de développement. Là où des modifications auraient eu un coût important, voir prohibitif sur le projet, tous les changements sont permis. L'IHM et la navigation entre les différentes pages a été plusieurs fois revuessans aucune difficultés.

Le développement est complètement linéaire. Il n'y a aucun poids de l'existant sur les développements des nouvelles fonctionnalités.

Le développeur est beaucoup plus proche du fonctionnel; le schéma graphique permet de structurer le modèle de l'application, et de mieux partager la logique applicative. Les niveaux de discussions sont essentiellement fonctionnels, il n'y pas de débat technique car toute la tuyauterie technique est issue du produit. Enfin, il n'y a aucun bug technique dans l'implémentation du projet. La qualité du développement est là, constante sur l'ensemble de l'application.

En conclusion, c'est un progrès considérable de développer et concevoir une application complexe, en si peu de temps, et avec si peu de code (là où nous envisagions de diviser le volume de code par 10, nous allons plutôt considérer un facteur 50 !) ; et comme nous le faisions remarquer en cours de projet, s'il est arrivé parfois que la voiture tombe en panne, pour cause de quelques bugs techniques, et que nous devions la pousser sur quelques mètres, nous sommes arrivés à bon port, et c'est beaucoup plus rapideplus confortable et nettement moins fatiguant que la charrette !

Classé sous : , , , ,