Bonjour,
Ceci est un long message qui explique étape par étape mon parcours avec Windev, j'ai envoyé ce même message au support de PCsoft et j'attends leur réponse, je poste ce message ici également en guise de témoignage afin que les potentielle développeur qui se demanderai si aquiérir Windev est une bonne idée sache concrètement vers quoi ils vont et quelles sont les limitations.
Je travaille dans une entreprise qui vend des caisses enregistreuse, nous avons développer une application pour Windows sur Windev et celle-ci fonctionne correctement.
Plus en plus de client nous ont demandé une version mobile du programme afin de pouvoir être plus efficace.
Nous avons donc développer une nouvelle application sur Windev Mobile sur Android en repartant de 0. Cela à eu plusieurs effet de bord indésirable étant donner que les deux programmes (desktop et mobile) devaient travailler ensemble. Si aujourd'hui la situation s'est stabilisée il reste encore malgré tout des différences sans compter que lorsque l'on travaille sur la version desktop il ne faut pas oublier de modifier le code du mobile en conséquence (ce que l'on oublie de faire très fréquemment).
Il a été décidé de faire une nouvelle version du programme partant de 0 et je me suis dis que j'allais séparer l'application en deux grande partie, le cœur qui contiendrait la logique de l'application et qui serai partagée via le GDS entre les deux plateformes et l'interface qui évidement est dépendante de la plateforme.
Sauf que Windev Mobile Android dispose vraiment de BEAUCOUP moins de fonction que Windev ce qui rend les choses vraiment très pénible pour justement concevoir deux applications avec un socle commun.
Pour ma par je suis un grand utilisateur de POO, cela permet de bien découper le code en augmentant la lisibilité, la modularité et la réutilisabilité, surtout avec l'utilisation design pattern MVC (ce que vous appelez MVP).
Une notion très importante dans ce design pattern c'est le Modèle, autrement dis les données. En Windev ont à déjà une partie de cette couche avec les fichiers (mot dans lequel j'englobe le concept d''analyse), et c'est déjà très bien… sauf que cela ne suffit pas. Les fichiers ne sont pas des classes, on ne peu donc pas les étendre. Exemple, j'ai un fichier ligne_commande contenant les détails d'une commande, dedans j'ai (entre autre) les rubriques prix_unitaire et quantite mais je ne stocke pas le total car je peux le calculer, je ne puis déclarer une fonction calculPrixTotal via la fichier, ce que je peux faire dans une classe.
Par ailleurs, un très grand manquement aussi avec cette couche modèle actuellement fournie dans Windev c'est la notion d'ORM ou Object Relation Mapper, pourtant tout est réuni pour offrir cette fonctionnalité.
Qu'est-ce que c'est ? Prenons un exemple, un fichier ligne_commande et un fichier produit, dans le fichier ligne commande on a une rubrique IDproduit qui est une clé étrangère vers le fichier produit, dans le code si je fais une boucle sur le fichier ligne_commande et que je veux accéder au information de produit je dois faire un HLitRecherchePremier(produit, IDproduit, ligne_commande.IDproduit), bon c'est un peu lourd à écrire mais sa marche. Sauf que si on commence à vouloir mettre en mémoire ses informations par exemple dans cette boucle je veux comparer ce produit trouvé avec un autre bah je suis complètement bloqué, soit je dois déclarer une structure/classe qui va jouer le rôle de mémoire tampon, on pourrait utiliser la variable de type Enregistrement mais ce type de variable n'est pas disponible en Windev Mobile Android.
Bref, avec ce que Windev propose on est quand même limité, l'idéal serai de pouvoir faire ligne_commande.produit et hop on est sur le produit associé.
Etant donner que la couche des données est la plus importante et que l'on peu gagner un temps précieux, tant en terme de temps de développement, que de débugage, que de temps de traitement (récupérer une informations en mémoire sera toujours plus rapide que d'aller la recharger deux fois de suite via le réseau) Du coup, je me suis atteler à écrire moi même mon ORM.
Au départ j'ai voulu utiliser les outils que Windev me proposait, donc en utilisant l'analyse utiliser le concept de mapping, une classe CommandeModele mappée sur le fichier commande et les différents attributs mappé sur les rubriques du fichier.
Malheureusement… encore une fois en Windev Mobile Android, l'utilisation de ses concepts ne fonctionne pas alors que je le rappelle, le but de la manœuvre est d'avoir un socle commun entre l'application mobile et desktop.
Sans compter que si Windev est capable depuis une instance de la classe CommandeModele de déterminer que c'est le fichier commande qui est rattacher l'inverse est impossible, je ne puis donc faire pclLigneDetail.getFichierAssocié("commande"), hors c'est quand même plus lisible que de devoir écrire sur deux lignes
clCommande est une CommandeModele() pclLigneDetail.getFichierAssocié(clCommande)
Il faut bien se rendre compte que l'on va écrire sa absolument tout le temps, parceque finalement, un programme, c'est manipuler des données… et concrètement on manipule tout le temps des "fichiers" (au sens HFSQL) ou des variables intermédiaire pour écrire finalement dans ses fichiers (logique c'est eux qui gère la persistance).
Du coup j'en suis venu à laisser tomber le mot clé mapping proposer par Windev en le faisant moi même, J'ai écris une classe Modele à partir de laquelle les classes modèles en hériterons et cette classe propose des fonctions du style mappingFichier, le résultat étant stocker dans un tableau global permettant de faire le lien commande -> CommandeModele.
Donc tout sa c'est bien joli, je peux enfin écrire un code du style pclLigneDetail.getFichierAssocié("commande") sauf qu'il faut encore coder cette fonction getFichierAssocié… hors le problème c'est qu'à ce stade on a aucune idée de qui est la clé étrangère/primaire dans les fichiers… évidement, on a définit les liaisons entre ses fichiers dans l'analyse et en Windev on peu récupérer la liste des liaisons, magnifique ! ou pas, Windev Mobile Android ne supporte pas cette fonction.
On ne se démonte pas, puisque l'on ne peu récupérée celle qui sont définie on va tout simplement les déclarer dans les classes modèles, donc j'ai écris une fonction ajouteLiaison également stockée dans un tableau global.
Avec sa je peux enfin récupérer un enregistrement associé, bon passons le fait que j'ai du écrire une fonction newModele dans chaque modèle car on ne peu pas faire (en Windev Mobile Android) un "new sClasse", je peux donc faire le code de récupération de données
Une fois que l'on a exécuter le traitement, par exemple ajouter une ligne_commande à une commande sa serai bien d'afficher le résultat à l'écran quand même, par exemple un joli tableau contenant l'ensemble des ligne d'une commande données.
Windev permet de créer des table lié à un fichier de données ou une requête, et c'est vrai que sa c'est très bien, en Windev il est également possible de lier des table à des variables et sa aussi c'est très bien, sauf un petit bémol, il n'est possible de lié qu'a des attribut publique où des propriété. Hors en POO un des concept fondamental c'est de n'avoir absolument aucun attribut publique, on accède aux informations que via des assesseur, no problèmo suffit de définir des propriétés (et sa d'ailleurs c'est quelque chose de très sympa en Windev).
Le seul point noir c'est que de nouveau… en Windev Mobile Android les propriétés de classe ne sont pas supportée, sans compter que dans l'absolu la liaison de table vers des variable ne sont pas supportée non plus.
Bon, reste plus qu'une possibilité, c'est de remplir par programmation la table et enfin, on a le résultat à l'écran tant en Windev qu'en Windev Mobile Android.
Après quelques essais et analyse de besoin de ma future application, je me dis que je vais avoir quand même besoin d'afficher beaucoup de table et que je trouve sa dommage de devoir à chaque fois écrire un parcours de boucle dans le but de représenter le contenu d'une variable tableau à l'écran.
Je me suis donc dis, s'il n'y a pas moyen de faire des liaisons rien ne m'interdis de faire une classe utilitaire avec laquelle je ferai à l'initialisation de la fenêtre declare(Table_detail, "COL_prixTotal", "getPrixTotal") et lorsque je dois afficher j'écris affiche(Table_detail, tabDetails) et grâce aux déclarations je sais que je dois remplir la colonne COL_prixTotal avec la methode getPrixTotal.
De cette manière j'écris une fois pour toute le code qui remplis le tableau et je n'ai qu'a écrire une ligne pour remplir le tableau.
Dans le code de la fonction affiche j'écris donc nIndice = TableAjouteLigne(champTable) et après grâce aux indirections {champTable + "." sPropriete, indChamp}[nIndice] = ExecuteTraitement(pclModele, sGetter)
Si cela fonctionne bien en Windev, encore une fois, en Windev Mobile Android je ne puis le faire étant donné que les indirections ne sont disponible que sur des variables globale, enfin, c'est ce que dit la documentation car dans mes test une indirection sur un champ ou sur une rubrique fonctionne assez bien.
Avant de me décider pour écrire un code de déclaration des liens d'une table dans l'initialisation de la fenêtre je m'étais dis que je pourrai le faire automatiquement en fonction du nom des colonnes, donc dire que la table details est basé sur le fichier ligne_commande et donc si le nom de la colonne existe comme propriété du modèle alors je remplis automatiquement la colonne avec la valeur.
Cependant j'étais embêter dans le cas où je créais une colonnes n'ayant pas de rapport avec le Modèle car systématiquement je tentais d'executer une fonction qui n'existais pas, si en Windev il existe la fonction ChercheProcédure, à nouveau celle-ci est indisponible en Windev Mobile Android, du coup pour pallier à ce manque plutôt que de déclarer des attributs à mes classe et des assesseur, j'ai définit dans ma classe modèle des fonction getAttribut et setAttribut permettant d'accéder et de modifier un attribut donner tout en me donnant la possibilité d'écrire une méthode isAttributExiste permettant de régler cette question.
A partir de là, je me suis dis, finalement dans mes modèles je déclare les fichiers, les attributs ainsi que les liaisons donc finalement… plus du tout besoin d'analyse ! L'intérêt de supprimer l'analyse étant de ne pas à avoir à maintenir d'un coté l'analyse et donc lorsque l'on ajoute une rubrique devoir le faire à la fois dans l'analyse et à la fois dans la classe modèle concernée.
J'ai donc créé un projet sans analyse et j'ai écris une fonction de génération d'un code SQL à partir de mes classes modèle afin d'adapter la structure base de données.
Cela fonctionne bien, sauf pour la création d'une clé primaire, dans ma requête j'écris une requête "CREATE TABLE commande (IDcommande BIGINT PRIMARY KEY AUTO_INCREMENT)" si le champ IDcommande est bien créé en type primaire, celui-ci est sur 4 octets et non 8. J'ai signaler le problème au support gratuit et l'on m'a juste répondu "pourquoi vous faite sa ?" J'ai expliqué rapidement mais on ne m'a jamais répondu. Cependant si je signale un problème je m'attends à ce que l'on me dise que vous travaillerai sur un correctif, c'est bien gentil de me proposer une façon de contourner (avec les description de fichier) sauf que de nouveau… ce n'est pas possible en Windev Mobile Android, hors je le rappelle, mon but ici est d'écrire un socle commun pour les différentes plateforme.
Par ailleurs, si je peux exécuter correctement mes ordres SQL de modification de structure correctement sur Windev avec un HFSQL C/S cela ne fonctionne pas avec Windev Mobile Android… pour une raisons que j'ignore d'ailleurs étant donné que le mobile se connecte sur le même serveur HFSQL C/S et que j’exécute mes requête avec la constante hRequêteSansCorrection, logiquement le mobile ne devrai que simplement transmettre la requête au serveur, qui, quelque soie le client devrai exécuter la requête.
Si Windev Mobile Android n'arrive pas à créer des fichiers sur un serveur HFSQL distant, il n'y arrive pas non plus en local, j'ai tenter de définir une connexion avec le provider hAccèsHF7 ou hAccèsNatifSQLite sans que mes ordre CREATE TABLE ne soie pris en compte, comment faire ? J'ai besoin des données en locale afin de palier à une pertes de réseau.
Lors de mes tests avec un terminal Android j'étais surpris de toujours avoir mes champs complètement vide alors qu'avec le simulateur ils étaient correctement remplis. Après de longue recherche j'ai finalement trouvé l'origine du problème, dans ma classe modèle pour le stockage des attributs dans le bon type j'ai créé une classe Attribut qui définit comme méthode abstraite getValue et setValue, en android une erreur "information" est levée signifiant que ses méthode n'ont pas de valeur de retour, lorsque j'avais rencontré cette erreur je l'avais ignorée car elle ne portait pas à conséquence dans le simulateur (sans me douter alors qu'en exécution cela ne fonctionnerai pas). Il n'est pas normal qu'une redéfinition d'une méthode abstraite ne puisse pas renvoyer de valeur !
Voilà, tout ce message pour relater mon aventure avec Windev, dont le but et encore une fois, de pouvoir écrire un socle commun entre le desktop et le mobile, car évidement je n'aurai voulu faire tout cela qu'en desktop que j'aurai rencontré beaucoup moins de problème. PCsoft vend son produit avec les slogans suivant: "Grâce à Windev Webdev et Windev mobile, une même source s’exécute sur plusieurs plateformes", "Un code unique pour toutes les cibles". Visiblement ce n'est pas atteint !!!!
Le but n'est pas juste ici de se plaindre des problèmes que je rencontre mais de trouver des solutions rapide aux problèmes que je rencontre afin que je puisse continuer de travailler, car comme je suis là le développement de mon application est stopper, et donc à peu près en chômage technique car l'outil que j'utilise ne me permet pas d'atteindre mes objectifs.
J'espère avoir une réponse rapide, complète et constructive en retour.
Bien à vous.
-Signature-