Gestion des versions par héritage de Form
Date de publication : 01/06/2001
Par
Sylvain James (TeamB-FR) (Contributions)
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
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 tutorial é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.
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éparemment.
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 finaux. 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 fouilli de dossiers "dédiés" et forms. Et ceci avec simplicité !
A travers quelques exemples, nous allons construire une mini application 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 3 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 sur 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 3 projets qui correspondront respectivement à nos 3
versions. Nous appelleront 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.
- Sélectionnez le menu Fichier / Nouvelle application
Vous avez par défaut une fiche : form1.
- 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 aller 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 version.
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 3 actions :
Ensuite nous implémentons le code spécifique à chacune de ces actions (leur méthode Execute), en double cliquant sur
chacune d'elle. 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 fournies.
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éfault 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éfault donc nous la supprimons du nouveau projet.
Maintenant cela commence à devenir interessant... 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 2...
Constatons :
Maintenant que les constatations sont faites, les unités qui ont été ajoutées au projet sont :
En fait uBasePassList 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 sur 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 :
- Ajout au référentiel de la version Personnelle
- Ajout 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 3 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 bug est signalé dans la version Demo, disons lors de l'enregistrement d'un compte :
Vous pouvez corriger ce bug et ensuite recompiler les 3 versions...et là encore magie de Delphi :

Vous n'allez quand même vous faire l'affront de sélectionner et de compiler les 3 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
|