Gestion des versions par héritage de form

Sylvain James (TeamB-FR)

L'objectif est de découvrir les possibilités offertes par l'outil référentiel de Delphi et d'en tirer profit pour organiser un projet qui doit être diffusé en plusieurs versions.

Ce tutoriel étant destiné aux débutants (et aux autres qui ont un peu oublié… :-), il est très riche en copies d'écrans, cela est voulu dans un but pédagogique.

- Titre : Gestion des versions par héritage de form

- Auteur : Sylvain James (TeamB-FR)

- Parution : 1 juin 2001

- Mise à jour : 31 décembre 2019

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 2001 Sylvain James. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Introduction

- II. Création du projet de base

- III. Définir la feuille DEMO comme fiche de référence

- IV. Conception de la version Personnelle

- V. Conception de la version commerciale

- VI. Compilation/Déploiement

I - Introduction

Il est courant pour les sociétés ou auteurs de proposer à leurs clients plusieurs versions de leurs logiciels. En général, on rencontre les formules suivantes :

- version de démonstration ;

- version personnelle, « light » ;

- version commerciale, « full ».

Souvent, des applications professionnelles distribuées en version de démonstration comportent au sein de leur exe les fonctions full, sauf que les menus ou actions respectives sont désactivés. Et donc votre démo se fait hacker valeureusement pour devenir une version fulldemo :-) Ce qui peut aussi correspondre à votre stratégie de diffusion sur le marché, mais dans le cas contraire, vous avez tout intérêt à suivre les conseils ci-dessous.
Vous l'avez compris, le but est de pouvoir développer plusieurs versions, chacune étant compilée séparément.
Il en va de même pour les applications qui comportent des fonctions utilisateurs et des fonctions d'administration. La version fournie aux administrateurs peut être différente de celle fournie aux utilisateurs finals. C'est un choix, le profilage peut aussi s'effectuer au sein du même exe.

Delphi nous offre les outils adéquats pour compiler plusieurs versions avec dégradé de fonctionnalités sans s'encombrer de multiples mises à jour dans un fouillis de dossiers « dédiés » et forms. Et ceci avec simplicité !

À travers quelques exemples, nous allons construire une miniapplication qui va montrer les différents mécanismes utilisés.

Mini cahier des charges
L'application devra permettre la saisie l'enregistrement et l'impression d'une liste de comptes avec mot de passe et de user dans un fichier texte, sans cryptage. Le but est de compiler trois versions différentes :

- une version DEMO qui ne permet les fonctions précitées ;

- une version PERSONNELLE avec les fonctions précitées + l'impression ;

- une version COMMERCIALE qui offre en plus la possibilité d'importer une liste de mots de passe existante.

Bien sûr les fonctionnalités proposées sont symboliques et n'ont qu'une valeur éducative.

Prêts ? Alors, allons-y étape par étape.

II - Création du projet de base

En premier lieu, sachons que nous allons créer un groupe de projets, qui contiendra trois projets qui correspondront respectivement à nos trois versions. Nous appellerons le projet global : PassList.
On doit commencer par développer les éléments de la version la moins riche en possibilités, celle à partir de laquelle on va s'appuyer (hériter) pour développer les autres. Ici il s'agira de la version DEMO, car toutes les autres versions possèdent ses fonctionnalités.

1. Sélectionnez le menu Fichier / Nouvelle application
Vous avez par défaut une fiche : form1.

2. Activez le raccourci clavier CTRL + ALT + F11 pour ouvrir le gestionnaire de projet accessible aussi via le menu Voir / Gestionnaire de projet.

La première chose à faire est de renommer le nom du groupe de projet : « PassList » en ouvrant le menu contextuel de l'item du groupe de projets et en sélectionnant Enregistrer le groupe de projets sous…

Dans l'ordre Delphi va vous demander d'enregistrer les unités, les projets et enfin le groupe de projet. En pratique vous allez enregistrer dans le dossier de votre choix :

- la première unité ouverte par défaut avec le nom « uBasePassList.pas » ;

- le premier projet ouvert aussi par défaut avec le nom « PassListDemo.dpr » ;

- et enfin le groupe de projets sous le nom « PassList.bpg ».

Vous devez avoir sous vos yeux la fenêtre suivante :

Vous êtes maintenant prêt pour l'implémentation de la version DEMO qui va servir de base aux autres versions. Nous allons mettre en place :

- un menu ;

- une zone d'édition pour la saisie de l'intitulé du compte ;

- une zone d'édition pour la saisie d'un nom d'utilisateur ;

- une zone d'édition pour la saisie d'un mot de passe ;

- une liste pour afficher les comptes ;

- un bouton pour Ajouter, un pour Enregistrer, un pour supprimer ;

- un composant ActionList pour centraliser tout ça et coordonner l'action des boutons avec le menu (au passage ça ne fera pas de mal…:-)

Voilà à quoi ressemble la form frmBasePassList :

En double-cliquant sur le composant ActionList, vous ouvrez l'éditeur d'actions. Ajoutez trois actions :

Ensuite nous implémentons le code spécifique à chacune de ces actions (leur méthode Execute), en double-cliquant sur chacune d'elles. Nous ne détaillons pas le code ici, car l'objet concerne le référentiel. Vous retrouverez l'implémentation complète dans les sources fournis.

Donc on part du principe que maintenant notre version de démonstration fonctionne.

III - Définir la feuille DEMO comme fiche de référence

Avant de passer à la version Personnelle, il faut ajouter au référentiel les feuilles dont on voudra hériter.

Ici c'est la form « FromBasePassList » qui va nous servir de base pour les versions suivantes.

Ajoutons-la au référentiel en ouvrant le menu contextuel de la feuille et en sélectionnant 'Ajouter au référentiel' :

On arrive sur le dialogue suivant :

On remplit les champs et on valide…et voilà votre fiche fait partie du référentiel. Au passage, sachez que Delphi stocke son référentiel dans le fichier DELPHI32.DRO par défaut placé dans le dossier BIN de Delphi.

IV - Conception de la version Personnelle

Cette version sera implémentée dans le même groupe de projet que précédemment, mais dans un nouveau projet qui s'intitulera PassListPERSO. On y ajoutera une fonction d'impression. Commençons par créer ce nouveau projet. On retourne dans le gestionnaire de projet (CTRL + ALT + F11) et dans le menu contextuel du groupe de projet, on sélectionne 'Ajouter un nouveau projet'.

Sélectionnez Application, car votre nouveau projet sera compilé aussi en un exe classique. Delphi vous crée un nouveau projet, qui fait partie du groupe de projets du départ.
Par contre nous n'allons pas utiliser la nouvelle feuille créée par défaut donc nous la supprimons du nouveau projet.

Maintenant cela commence à devenir intéressant… Au lieu de créer une nouvelle fiche vierge, nous allons hériter de la fiche DEMO construite précédemment. C'est très simple, nous allons cliquer sur l'icône Nouveau :

Un dialogue s'affiche et nous allons sélectionner l'onglet qui correspond à celui dans lequel nous avons placé notre fiche DEMO dans le référentiel, soit l'onglet 'Fiches' :

Nous sélectionnons l'icône représentant la fiche référencée 'ref_FormBasePassList'. Nous sélectionnons également l'option 'Hériter'.

Pourquoi hériter ? Parce que la nouvelle fiche héritera de toutes les fonctionnalités de la fiche de base, nous pourrons ajouter nos propres modifications, la fiche de base n'en souffrira pas. Par contre, si on effectue des modifications dans la fiche de base, elles se répercuteront dans nos projets qui utilisent cette fiche du référentiel.

Le système et l'approche sont identiques à la gestion des Frames, hormis que l'héritage est implicite chez ces dernières.

Les autres options possibles étaient Copier et Utiliser.

Choisir Copier signifiait que vous souhaitiez travailler avec la form héritée de la form de référence sans que les modifications intervenant sur la form héritée ou sur la form de référence ne se répercutent l'une sur l'autre.

Choisir Utiliser impliquait une plus grande prudence. En effet, dans ce cas les modifications ultérieures auraient été bidirectionnelles, en décodé cela signifie que toute modification, qu'elle se fasse sur la form de référence, ou sur la form utilisée, sera répercutée vers l'autre, et par extension dans tous les projets utilisant la form de référence.

Une fois que l'on a cliqué sur OK pour valider notre choix, notre gestionnaire de projet ajoute cette form au nouveau projet créé précédemment. Mais on s'aperçoit qu'en fait, il a ajouté non pas une form au projet, mais deux…

Constatons :

Maintenant que les constatations sont faites, les unités qui ont été ajoutées au projet sont :

- uBasePassList ;

- Unit1.

En fait uBasePassList n’est ni plus ni moins que l'unité de référence, et Unit en est une unité héritée. Il est normal de les retrouver toutes les deux dans le même projet. Un exercice amusant consiste à afficher (F12) chacune de ces deux form et de les disposer de façon à les avoir à l'écran simultanément. Ajoutez un élément sur la form de référence (FormBasePassList) et vous verrez cet élément automatiquement répercuté dans la nouvelle form, form1. Magiiique :-)

Il faut signaler également qu'il est impossible de retirer du projet une unité (et sa form associée) dont a hérité une autre unité du même projet, c'est logique.

Maintenant que notre structure est prête, enregistrons notre nouveau projet avec des noms plus explicites, par exemple PassListPerso.dpr pour le projet et uPersoPassList pour la nouvelle unité (précédemment unit1).

Ouvrons la forme dérivée : FormPersoPassList, et ajoutons au menu, sur un bouton, et à la liste d'actions la fonction d'impression avec son implémentation :

C'est aussi simple ! Si maintenant vous effectuez des changements dans la version Demo, ils se répercuteront automatiquement dans la version Perso.
Nous allons implémenter le gestionnaire d'évènement OnExecute de l'action ActImprim en affichant un simple message.
En double-cliquant sur ce gestionnaire (OnExecute) dans l'inspecteur de propriétés, la structure de code suivante est créée :

procedure TFormBasePersoList.ActImprimExecute(Sender: TObject);
begin
inherited;

end;

On remarque la présence inhabituelle de inherited… En effet, avant que votre code soit exécuté, inherited va appeler le code de la même action, mais dans la form dont on a hérité, bien sûr si le gestionnaire d'évènement a été implémenté.

Dans notre exemple, l'action ActImprim n'existait pas dans la form dont on a hérité, donc Inherited sera simplement ignoré par le compilateur.

V - Conception de la version commerciale

La version commerciale nous offre les mêmes fonctions que précédemment, avec en plus une fonction d'importation d'une liste de comptes. De quelle form allons-nous dériver ?

Puisque vous êtes des développeurs(euses) consciencieux, vous avez très bien pensé et défini votre projet à l'avance :-) donc comme les fonctions de la version Commerciale devront comporter les fonctions de la version Personnelle, on héritera cette fois de la form version Perso.

Si par automatisme, vous héritiez de la version Demo, la fonction d'impression ne serait pas disponible ! Pour hériter de la version Perso, il faut refaire le même cheminement :

- ajouter au référentiel de la version Personnelle ;

- ajouter d'un nouveau projet ;

- hériter de la version Personnelle pour bâtir la version Professionnelle ;

- enregistrer le projet en attribuant des noms en rapport avec la version.

Après lecture des recommandations précédentes, il n'est plus à douter de votre capacité à développer vous-même cette partie sans aide extérieure.

VI - Compilation/Déploiement

Nos trois versions sont prêtes, et vous avez la conscience tranquille… là encore il ne s'agit pas d'une boutade, car ceux qui se lancent dans un développement « sauvage » (sans respecter le principe d'héritage) d'une application en plusieurs versions, s'exposent à un véritable cauchemar, notamment lors des phases de débogage et/ou de mise à jour.

Si par exemple un bogue est signalé dans la version Demo, disons lors de l'enregistrement d'un compte :
Vous pouvez corriger ce bogue et ensuite recompiler les trois versions… et là encore magie de Delphi :

Vous n'allez quand même vous faire l'affront de sélectionner et de compiler les trois projets un par un ?! :-)))

J'espère que cette présentation du référentiel était suffisamment claire et explicite, dans le cadre de l'objectif initial, c'est-à-dire de développer plusieurs versions différentes d'un soft. L'avantage est que l'héritage permet de se concentrer totalement sur les fonctionnalités et non leur répartition, que seules les fonctionnalités spécifiques à une version sont présentes (si l'on observe l'ensemble des versions démo des softs du commerce, il faut croire que peu de développeurs connaissent le concept héritage/référentiel…).

Dans tous les cas, il faut se rappeler que cette souplesse garantit l'efficacité et la robustesse du projet, mais aussi que le référentiel peut servir dans d'autres contextes, comme la reprise de projet par exemple.

Téléchargez les sources du projet : softmultiversions.zip
Dans le dossier où vous aurez décompressé ce zip, ouvrez le groupe de projets PathList.bpg.

Sylvain James
Développeur / Formateur