Refactoring avec Delphi 2007
Date de publication : 22/05/2007
Par
Sébastien Doeraene (sjrd.developpez.com)
Présentation des outils de refactoring de Delphi 2007 ne nécessitant pas le support de Together dans le projet.
Introduction
I. Renommer
I-A. But de l'opération
I-B. Applicable sur...
I-C. Utilisation
I-D. Remarques
II. Extraire une méthode
II-A. But de l'opération
II-B. Applicable sur...
II-C. Utilisation
II-D. Remarques
III. Extraire une chaîne de ressources
III-A. But de l'opération
III-B. Applicable sur...
III-C. Utilisation
III-D. Remarques
IV. Déclarer une variable ou un champ
IV-A. But de l'opération
IV-B. Applicable sur...
IV-C. Utilisation
IV-D. Remarques
V. Modifier les paramètres
V-A. But de l'opération
V-B. Applicable sur...
V-C. Utilisation
V-D. Remarques
VI. Liens
Introduction
Nous savons tous qu'un code écrit n'est pas figé. Qu'une modélisation rédigée n'est pas permanente. Il arrive plus que
fréquemment qu'il faille repasser sur le travail déjà accompli. Que celui-ci l'ait été dans les règles de l'art ou,
comme il est coutume de dire, "à l'arrache".
Des besoins récurrents sont le renommage d'objets ou l'insertion de données supplémentaires au sein de classes. Dans le
cadre d'une traduction de logiciel, on peut aussi vouloir transformer les chaînes littérales en chaînes de ressources.
On appelle ces opérations des opérations de refactoring (traduit parfois en français comme réusinage).
Le fait est que ces opérations sont souvent ennuyeuses, longues, et donc sujettes à beaucoup d'erreurs. Imaginez toutes
les conséquences que peut avoir le fait de renommer une propriété d'une classe !
Aujourd'hui, on trouve de plus en plus d'outils de refactoring. Des traitements automatiques sur le code ou la
structure UML d'un projet, qui effectuent ces tâches en prévenant les erreurs possibles.
Depuis Delphi 2005, l'EDI propose un certain nombre d'opérations de refactoring. Si deux ou trois sont très intuitives,
la plupart méritent un mot d'explication. Ce tutoriel propose de montrer l'utilisation des outils de refactoring de
Delphi 2007 ne nécessitant pas le support de Together. Ces dernières feront sans doute l'objet d'un futur tutoriel.
Chacune des opérations décrites ci-dessous peut être trouvée dans le menu Refactoring de l'EDI, après avoir
positionné le curseur correctement. Soit par le menu contextuel de l'éditeur de code, sous-menu Refactoring.
Les différents outils que je vais vous présenter ici fonctionnent tous sur le même schéma global, excepté le premier
(renommer) :
- Vous sélectionnez les options du refactoring choisi ;
- Vous validez les options : aucune modification n'a lieu à ce moment ;
- Dans la fenêtre Refactorings, vous pouvez voir les modifications qui vont être apportées ;
-
Cliquez sur le bouton
Refactoring de cette fenêtre pour
exécuter effectivement les modifications ;
- Vous pouvez éventuellement annuler les modifications au moyen du bouton prévu à cet effet.

Fenêtre Refactorings
La différence pour Renommer est que vous pouvez, au moyen d'une case à cocher, choisir si vous voulez
immédiatement appliquer le refactoring ou pas.
I. Renommer
Si cette opération est en haut de la liste, ce n'est pas un hasard. La fonction renommer est non seulement la
plus utilisée, mais également la plus simple à utiliser.
I-A. But de l'opération
Renommer un type, champ, variable, méthode, propriété, ou tout autre identificateur - excepté une unité, en mettant à
jour automatiquement toutes les références à celui-ci.
I-B. Applicable sur...
L'opération de renommage est applicable sur tout identificateur qui n'est pas une unité. Pour les méthodes à liaison
dynamique (virtuelles et dynamiques, et leurs surcharges), le renommage n'est permis que si la déclaration initiale
(celle qui porte le mot clef virtual ou dynamic) se trouve dans un projet ouvert. Cela est bien sûr
toujours vrai si vous renommez directement cette déclaration initiale.
I-C. Utilisation

Boîte de dialogue Renommer
Dans la boîte de dialogue qui apparaît, choisissez simplement un nouveau nom pour l'identificateur.
I-D. Remarques
- Lorsqu'elle est utilisée sur une méthode à liaison dynamqiue, les méthodes surchargées dans les classes enfantes et parentes sont également renommées automatiquement.
- Cette opération ne fonctionne pas bien avec les routines et méthode déclarées overload.
II. Extraire une méthode
C'est bien connu, on commence à implémenter les méthodes de sa classe, et on remarque qu'on utilise plusieurs fois la
même portion de code. Bah... Copier-coller, à la vieille méthode... Et bonjour les duplications de code.
Mais non ! L'extraction de méthode vous permet de rationnaliser votre code, et de factoriser les morceaux de code
récurrents en une nouvelle méthode.
II-A. But de l'opération
Le but de l'extraction de méthode est de construire automatiquement une nouvelle méthode, privée en général, dont le
code est une partie d'un code existant dans une autre méthode. Et cela en substituant les données externes au morceau de
code à des paramètres, et les résultats à des paramètres var.
Parallèlement, le code déjà écrit est remplacé par un appel à cette nouvelle méthode.
II-B. Applicable sur...
L'extraction de méthode est applicable sur un ensemble d'instructions au sein d'une méthode déjà écrite. Les
instructions concernées doivent être sélectionnées avant de lancer l'opération.
Il y a plusieurs exceptions à l'application de cette opération. Extrait de l'aide de Delphi 2007 :
- Seules les instructions peuvent être extraites, pas les expressions.
- Dans Delphi, les instructions qui contiennent un appel à inherited ne peuvent pas être extraites.
- Les instructions contenues dans une instruction with ne peuvent pas être extraites.
- Les instructions qui appellent une procédure ou fonction locale ne peuvent pas être extraites.
J'ajouterais encore :
- Du code contenant un appel à exit, break, continue ou goto devant faire sortir l'exécution du morceau sélectionné ne peut pas être extrait.
- Des instructions assembleur ne peuvent être extraites, que ce soit dans leur entièreté (tout le bloc asm...end) ou pas.
II-C. Utilisation

Boîte de dialogue Extraire une méthode
Sélectionnez tout d'abord l'ensemble des instructions devant être factorisées dans la nouvelle méthode. Sachez que cette
sélection sera automatiquement étendue pour couvrir les instructions dans leur entièreté. Cela signifie par exemple que,
si vous sélectionnez une instruction if, le bloc dépendant de celui-ci, ainsi que du else correspondant
éventuel, seront ajoutés à votre sélection.
La boîte de dialogue de l'opération de refactoring vous montre un aperçu de la méthode qui sera créée. Vous pouvez alors
lui donner le nom que vous souhaitez. Validez, et l'opération s'exécute.
II-D. Remarques
- Cette opération gère aussi bien les routines que les méthodes, ou encore les méthodes de classe. Les nouvelles méthodes créées sont toujours du même type.
- L'extraction de méthode ne génère que des procédures, jamais de fonction. Les résultats sont renvoyés au moyen de paramètres var.
- Les méthodes générées sont toujours déclarées comme privées, et les routines n'ont pas de déclaration dans l'interface. À vous de déplacer/ajouter la déclaration si vous le désirez.
- Le contenu de la méthode extraite est réindenté à la "norme" CodeGear, et non tel que vous l'aviez écrit. Repassez donc dessus pour le remettre en forme selon vos goûts et habitudes.
III. Extraire une chaîne de ressources
Vous reprenez un ancien code que vous devez internationaliser ? Ou vous n'avez tout simplement pas encore la bonne
habitude de déclarer les chaînes à traduire en chaînes de ressources ? Grâce à cette opération, vous pouvez facilement
transformer une constante littérale chaîne en une chaîne de ressources.
III-A. But de l'opération
À partir d'une constante littérale chaîne - en d'autres mots, une chaîne dans votre code -, déclarer une chaîne de
ressources (resourcestring) et remplacer l'ancienne référence par cette chaîne de ressources.
III-B. Applicable sur...
Cette opération est applicable sur toute chaîne de caractères littérale, à l'exception des cas suivants :
- Les valeurs de constantes chaînes ;
- Les valeurs par défaut de paramètres de routine ;
- Les chaînes qui sont déjà des chaînes de ressource (c'est bête à dire mais c'est le cas).
III-C. Utilisation

Boîte de dialogue Extraire une chaîne de ressource
Le curseur placé sur la chaîne à extraire, lancez l'opération de refactoring. Spécifiez simplement le nom que vous
souhaitez donner à la chaîne de ressources, et validez.
III-D. Remarques
- Les chaînes extraites sont placées dans la section implémentation de l'unité courante. Si vous les voulez ailleurs, vous devrez les déplacer à la main ensuite.
- Seule la chaîne sélectionnée est remplacée par le nom de la chaîne de ressources. Si cette chaîne est utilisée plusieurs fois dans votre code, vous devrez remplacer les autres occurences à la main.
IV. Déclarer une variable ou un champ
Il arrive très fréquemment que, lors du codage, on ait besoin d'une variable supplémentaire, ou d'un champ de classe non
prévu. Cette opération permet de déclarer automatiquement de nouvelles variables locales, et de nouveaux champs.
IV-A. But de l'opération
À partir d'un identificateur non déclaré - souligné en rouge par l'éditeur -, déclarer une variable locale ou un
champ de classe.
IV-B. Applicable sur...
Ces deux opérations sont applicables sur un identificateur non déclaré au sein d'une routine ou d'une méthode. Dans le
cas de l'extraction d'un champ, ce n'est valable que dans une méthode.
Bien que l'opération soit légitime pour l'identificateur MaVar dans MonObjet.MaVar, le résultat de
l'opération sera erroné.
De même, l'extraction de champ dans une méthode de classe est valide, mais crée un champ d'objet (les champs de
classe n'existent pas en Delphi), ce qui sera plus que probablement faux également.
IV-C. Utilisation

Boîte de dialogue Déclarer une variable
La boîte de dialogue de ce refactoring permet de choisir les choses suivantes :
- Le type de la variable/du champ ;
- S'il s'agit d'un tableau et, le cas échéant, son nombre de dimensions (nombre de array of) - c'est toujours un tableau dynamique qui est généré ;
- Dans le cas d'une variable, une éventuelle valeur initiale ;
- Dans le cas d'un champ, sa visibilité.
IV-D. Remarques
- Le refactoring vous empêche de choisir un nom qui entrerait, d'une manière ou d'une autre, en conflit avec un autre élément.
V. Modifier les paramètres
Vous avez codé une fonction, vous l'avez beaucoup utilisée, et vous devez la modifier. Mais vous avez alors besoin d'un
paramètres supplémentaire ! Aïe, tant de références à vérifier ! Ce refactoring permet de modifier les paramètres sans
effort, et sans danger.
V-A. But de l'opération
Modifier les paramètres d'une routine ou d'une méthode, et mettre à jour les appels à celles-ci.
V-B. Applicable sur...
Cette opération est applicable sur n'importe quelle routine ou méthode.
Attention toutefois : même si son utilisation est légitime sur une méthode servant d'accesseur à une propriété, la
propriété correspondante ne sera pas du tout modifiée. Il est donc impossible en pratique de s'en servir dans ces cas.
V-C. Utilisation

Boîte de dialogue Modifier les paramètres
La boîte de dialogue de ce refactoring est plus remplie que les autres. Elle contient une liste des paramètres, et des
boutons permettant de les modifier.
Les boutons Vers le haut et Vers le bas permet de changer l'ordre des paramètres.
Le bouton Ajouter vous proposera une boîte de dialogue permettant de donner le nom du champ, son type, une
éventuelle valeur par défaut et le statut d'entrée/sortie du paramètres (var, out et const).
 |
La valeur par défaut n'est pas ce que vous croyez ! Cela n'a aucun lien avec la valeur par défaut que vous pouvez
spécifier avec le = dans la déclaration. Celle-ci indique la valeur à placer dans les appels à la méthode, une fois le
refactoring effectué.
|
Le bouton Modifier permet de modifier un paramètres ajouté durant ce refactoring, au moyen de la même
boîte de dialogue. Pas d'en modifier un qui était déjà présent avant.
Enfin, le bouton Enlever supprime un paramètre.
Une fois le refactoring effectué, les déclarations sont parfaitement modifiées. En revanche, vous devrez repasser à la
main sur chaque appel. En effet, le refactoring ne fait que placer de nouvelles parenthèses, avec des virgules et les
valeurs par défaut, devant les anciennes parenthèses. Il faut donc tout remodifier.
Néanmoins, puisque le refactoring vous indique dans sa fenêtre d'exécution toutes les références à la routine/méthode,
ces modifications sont vites faites. Ce refactoring est donc tout de même très pratique.
V-D. Remarques
- Lorsque vous supprimez tous les paramètres d'une routine/méthode au moyen de ce refactoring, les déclarations reçoivent des parenthèses vides (), et les appels sont tout à fait inchangés.
VI. Liens

