Refactor : Refactoring avec Visual Basic .Net 2005

Ronald VASSEUR

Le refactoring correspond au processus d'adaptation d'un code existant dans l'optique d'une réutilisation, cela va d'une simple remise en forme à une modification plus importante dans la structure même du code. Jusqu'à maintenant, Visual Basic ne possédait pas de telles fonctionnalités, c'était l'apanage de C# notamment. Visual Studio 2005 corrige cela avec l'outil Refactor. Voyons sans plus tarder ce qu'apporte cet outil, et comment il fonctionne.

- Titre : Refactor : Refactoring avec Visual Basic .Net 2005

- Auteur : Ronald VASSEUR

- Parution : 16 août 2006

- Licence : Copyright ® 2006 Ronald Vasseur. 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

- Introduction

- Présentation du refactoring

- Présentation de Refactor for Visual Basic .NET 2005

- 1. Intégration dans Visual Studio 2005

- 1-1. Installation de Refactor

- 1-2. Intégration de Refactor dans Visual Studio

- 2. Présentation des fonctionnalités de Refactor

- 2-1. Fonctionnalités de base

- 2-2. Nouvelles fonctionnalités après enregistrement

- 2-3. Pour aller plus loin

- Ressources

- Conclusion

Introduction

Une chose que l'on reprochait il y a encore peu à Visual Basic était l'absence de fonctions de refactoring. Depuis Visual Studio 2005, notre langage préféré n'a plus rien à envier à C# dans ce domaine précis. Le salut en la matière vient d'un petit outil additionnel qui vient s'intégrer dans l'IDE de Microsoft. Il va sans dire que cet outil est gratuit ! Mais il existe aussi une version Pro qui elle est payante, mais nous verrons que la version de base satisfait nombre de scénarios fréquents, et que les besoins de refactoring les plus courants sont couverts. Dernier point avant d'entrer dans le détail, cet outil n'est paradoxalement pas un outil Microsoft, son développement à été confié par la firme de Redmond à un de ses partenaires, Developer Express.

Présentation du refactoring

Tout d'abord le terme consacré est un anglicisme : "refactoring", difficile à traduire facilement en français, on pourrait utiliser "refactorisation", mais la vraie signification est plutôt "remaniement". Ce refactoring intervient généralement pour améliorer, rendre plus clair, supprimer du code inutile, ou encore recycler du code existant. Voici une liste non exhaustive des éléments majeurs constituants le refactoring :

- Modification de la signature de méthodes

- Changement de l'ordre de paramètre

- Encapsulation de données

- Suppression de code mort

- Simplification d'expression

- Extraction de méthodes et de propriétés

- Renommer divers éléments

- Renversement des conditions (dans les If / End If)

- Création de surcharge de méthodes

- ...

Présentation de Refactor for Visual Basic .NET 2005

Refactor, l'outil de Developer Express, est un outil de refactoring gratuit pour Visual Basic 2005. Il s'intègre directement dans Visual Studio 2005, et petit détail sympathique, il est en français si vous utilisez une version française de l'IDE de Microsoft.

Refactor est également disponible dans plusieurs autres langues : Allemand, Anglais, Chinois (traditionnel et simplifié), Coréen, Espagnol, Italien, Japonais. Le téléchargement inclut toutes ces langues par défaut, donc pas la peine de se soucier de la version à télécharger.

Cet outil se présente sous la forme d'un "setup" de 9.3 Mo, et s'installe sur Visual Studio 2005, à l'exception des versions Express, chose que l'on peut regretter. La version Pro (qui coûte 99 dollars US) elle, s'installe également sur les versions 2002 et 2003 de Visual Studio, et prends également en charge le langage C#.

Refactor est disponible au téléchargement ici.

Voilà, Visual Basic à désormais son outil de refactoring, voyons comment il s'intègre dans notre IDE préféré.

1 - Intégration dans Visual Studio 2005

1-1 - Installation de Refactor

Tout d'abord, commençons par le commencement, l'installation. Alors attention cela va aller très vite, je ne vais pas faire de long discours, il suffit juste de cliquer sur "suivant"... Vous devriez pouvoir vous en sortir tout seul. Juste pour rappel, Refactor, dans sa version gratuite, s'installe uniquement sur Visual Studio 2005, versions Express non comprises.

1-2 - Intégration de Refactor dans Visual Studio

L'intégration dans Visual Studio est très bonne, en effet, il n'est pas la peine d'aller chercher l'outil dans un sous menu d'un menu annexe dans la boite de dialogue des options… Refactor est accessible directement depuis le clic droit de la souris. De plus dès qu'on l'utilise, vient, en surimpression au dessus du code, s'afficher une petite fenêtre listant les actions disponibles pour le code sélectionné. Voici une capture d'écran montrant cela :

Refactor intégré à Visual Studio 2005

Refactor est très rapide, et ne cause aucun ralentissement dans la saisie ou l'édition du code. Pour ne rien gâcher, cet outil est graphiquement très réussi, en effet, animations, images et couleurs viennent agrémenter l'utilisation des fonctionnalités disponibles.

Comme vous pourrez le découvrir un peu plus loin dans cet article, un petit tableau s'affiche pour lister les raccourcis clavier utiles pour mener à bien l'action de refactoring que vous avez entamé.

Refactor, bien que d'un éditeur tiers, s'intègre parfaitement à Visual Studio 2005, et par défaut, est chargé à l'ouverture de votre projet.

2 - Présentation des fonctionnalités de Refactor

Dans cette version Refactor intègre environ une vingtaine de fonctions de refactoring, à titre d'information la version Pro en intègre une cinquantaine. Pour bénéficier de quelques fonctions supplémentaires sur la version de base, vous avez la possibilité de vous enregistrer gratuitement chez Developer Express.

Remarque : Refactor est sensible au contexte, cela signifie simplement qu'il analyse le contexte du code sur lequel vous travaillez, et il ne proposera depuis le clic droit et le menu contextuel (ou depuis la petite balise qu'il incruste dans le code) que les fonctionnalités qui s'applique au code sélectionné ou sur la ligne courante. Par exemple, si vous ne vous trouvez pas dans la signature de la méthode, il ne vous sera pas proposé de réordonner les paramètres.

2-1 - Fonctionnalités de base

Dans ce paragraphe nous allons voir en détails l'ensemble des fonctionnalités de refactoring proposées par Refactor, cette liste exhaustive est certes un peu longue mais je pense que chacune des fonctionnalités mérite d'être connue. Dans la mesure du possible, dans cette partie, j'ai fait en sorte d'expliquer et d'illustrer mes dires par un exemple concret.

Réorganiser les paramètres : Réorganise les paramètres de la méthode actuelle, puis met à jour le code appelant pour répercuter le nouvel ordre.

Cela consiste simplement à changer l'ordre des paramètres dans la signature de la méthode. Cette opération se réalise à l'aide des flèches "droite" et "gauche" sur le clavier. Une animation se produit lors du déplacement, ce qui apporte beaucoup de lisibilité lorsque l'on utilise cette fonctionnalité.

Réordonner les paramètres

Changement de nom symbolique / Renommer: Renomme l'élément actuel et met à jour ses références.

Cette fonctionnalité permet de renommer une variable, une méthode ou une propriété, la modification sera répercutée dans l'ensemble du code. L'avantage est ici le fait que la modification est immédiatement réalisée sur le reste de votre code, pas d'erreur ou d'oubli possible. Nous verrons un peu plus tard qu'il existe aussi un "changement de nom sécurisé" qui s'avère bien pratique dans l'évolution de code existant.

Extraire une méthode : Crée une nouvelle méthode à partir du bloc de code sélectionné. La sélection est remplacée par le code appelant adapté pour appeler la nouvelle méthode déclarée.

L'explication se suffit à elle même, voici un exemple illustrant le "avant" et le "après" l'extraction de méthode.

Avant extraction

Public Function Ajouter(ByVal a As Integer, ByVal b As Integer) As Integer

Dim resultat As Integer
resultat = a + b

Return resultat

End Function

Après extraction

Private Function AjouterExtracted(ByVal a As Integer, ByVal b As Integer) As Integer
Dim resultat As Integer
resultat = a + b

Return resultat
End Function

Public Function Ajouter(ByVal a As Integer, ByVal b As Integer) As Integer

Return AjouterExtracted(a, b)

End Function

Vous voyez donc que cela est très pratique et permet notamment de simplifier de gros morceaux de codes en les divisant en de plus petites méthodes.

Créer une surcharge : Crée une méthode surchargée similaire à celle-ci, avec moins de paramètres.

En fonctions des besoins spécifiques de nos applications il arrive très souvent d'avoir besoin de méthodes présentant de multiples signatures. Refactor nous permet de réaliser cela très facilement. Voici comment cela se passe :

Nous allons retirer le paramètre "b" de la signature pour le passer dans le corps de la méthode. Ce qui, dans le code va nous donner :

Création d'une méthode surchargée

Private Function Ajouter(ByVal a As Integer, ByVal b As Integer) As Integer
Dim resultat As Integer
resultat = a + b

Return resultat
End Function

Private Function Ajouter(ByVal a As Integer) As Integer
Dim lB As Integer = 0
Return Ajouter(a, lB)
End Function

Extraire une propriété : Crée une nouvelle propriété à partir du bloc de code sélectionné. La sélection est remplacée par le code adapté pour référencer la nouvelle propriété déclarée.

Avant extraction de la propriété

Private _tauxChange As Double = 6.55957

Private Function Convertir(ByVal francs As Integer) As Double
Dim resultat As Integer
resultat = francs / _tauxChange

Return resultat
End Function

Après extraction de la propriété

Private _tauxChange As Double = 6.55957

Private ReadOnly Property MyProperty() As Double
Get
Return _tauxChange
End Get
End Property

Private Function Convertir(ByVal francs As Integer) As Double
Dim resultat As Integer
resultat = francs / MyProperty

Return resultat
End Function

Introduire une variable locale : Crée une nouvelle variable locale initialisée à l'expression sélectionnée. Remplace la sélection par la nouvelle variable.

Avant ajout d'une variable locale

Private Sub AfficheTexte()
Me.Label1.Text = "Developpez.com"
End Sub

Après ajout d'une variable locale

Insérer une temporaire : Remplace toutes les références à cette variable locale par la valeur d'origine de cette variable.

Ici c'est l'inverse de l'ajout d'une variable locale, on va donc supprimer le passage par une variable locale. Voici un exemple :

Avant refactoring

Private Sub AfficheTexte()
Dim monTexte As String = "Developpez.com"
Me.Label1.Text = monTexte
End Sub

Après refactoring

Private Sub AfficheTexte()
Me.Label1.Text = "Developpez.com"
End Sub

Fractionner la variable temporaire : Fractionne une variable locale dotée d'assignations trop nombreuses en déclarant une nouvelle variable locale à la première assignation à la suite de la première référence.

Attention, le code qui suit est loin d'être une référence des bonnes pratiques de programmation, il n'est là qu'à simple titre d'exemple !!

Avant fractionnement de la variable

Private Function demoFraction(ByVal chaine As String) As String

Dim s As String
s = chaine

Me.Text = s
s = "Developpez.com"

Return s

End Function

Après fractionnement de la variable

Private Function demoFraction(ByVal chaine As String) As String

Dim s As String
s = chaine

Me.Text = s

Dim z As String
z = "Developpez.com"

Return z

End Function

Déplacer l'initialisation vers la déclaration : Associe la déclaration de cette variable locale à sa première initialisation.

Avant déplacement de l'initialisation

Dim maVariable As String
maVariable = "Developpez.com"

Après déplacement de l'initialisation

Dim maVariable As String = "Developpez.com"

Séparer l'initialisation de la déclaration : Fractionne une déclaration initialisée de variable locale en une déclaration et une instruction d'initialisation distincte.

Ici nous allons faire l'inverse de ce que nous avons fait précédemment, nous allons séparer la déclaration et l'initialisation en deux étapes distinctes.

Avant refactoring

Dim maVariable As String = "Developpez.com"

Après refactoring

Dim maVariable As String
maVariable = "Developpez.com"

Rapprocher la déclaration de la référence : Déplace l'instruction de déclaration de cette variable locale à proximité de sa première référence.

Le rapprochement consiste en fait à rapprocher la déclaration de la variable au plus prêt de l'endroit où elle est utilisée, cela est particulièrement utile lorsqu'il y a beaucoup de lignes de code, on gagne en clarté, et en compréhension.

Avant le rapprochement

Private Function CompterCaracteres(ByVal chaine As String) As Integer

Dim resultat As Integer

Dim temp As String
temp = chaine
resultat = chaine.Length

Return resultat

End Function

Après le rapprochement

Private Function CompterCaracteres(ByVal chaine As String) As Integer

Dim temp As String
temp = chaine

Dim resultat As Integer
resultat = chaine.Length

Return resultat

End Function

Inverser la condition : Inverse la logique de cette instruction conditionnelle et permute les blocs If et Else.

Avant inversemment de la condition

If a > 50 Then
Return True
Else
Return False
End If

Après inversemment de la condition

If a <= 50 Then
Return False
Else
Return True
End If

Simplifier l'expression : Résout cette expression en sa forme la plus simple.

Avant simplication de l'expression

Private Function CalculNbMois(ByVal a As Integer, ByVal b As Integer, ByVal c As Integer) As Integer

Dim resultat As Integer

If Not (a <> 50) Then
resultat = b + c
Else
resultat = b + c * 2
End If

Return resultat

End Function

Après simplication de l'expression

Private Function CalculNbMois(ByVal a As Integer, ByVal b As Integer, ByVal c As Integer) As Integer

Dim resultat As Integer

If a = 50 Then
resultat = b + c
Else
resultat = b + c * 2
End If

Return resultat

End Function

Introduire une constante : Déclare une nouvelle constante, initialisée à la valeur de la chaîne ou du nombre sous le signe insertion.

Comme son nom l'indique, cette opération de refactoring va remplacer le contenu d'une variable par une constante, voyons ce que cela donne concrètement :

Sans constante

Dim maVariable As String = "Developpez.com"

Avec constante

Private Const STR_Developpezcom As String = "Developpez.com"
Dim maVariable As String = STR_Developpezcom

Encapsuler un champ : Encapsule un champ dans une propriété accessible en lecture-écriture et remplace toutes les références à ce champ présentes dans la classe par la nouvelle propriété déclarée.

Champ à encapsuler

Private maVariable As String = "Developpez.com"

Champ après encapsulation

Private maVariable As String = "Developpez.com"

Public Property MaVariable1() As String
Get
Return maVariable
End Get
Set(ByVal value As String)
maVariable = value
End Set
End Property

2-2 - Nouvelles fonctionnalités après enregistrement

En plus des fonctionnalités de refactoring intégrée, vous pouvez en avoir quatre de plus en l'échange de l'enregistrement (gratuit) de votre copie chez Developer Express sur cette page. A la suite de cet enregistrement vous aurez accès à un fichier en téléchargement, qui, une fois exécuté ajoutera les quatre fonctionnalités décrites ci-après.

Créer un contrat de méthode : Crée un contrat pour la méthode actuelle pour vérifier que les paramètres sont valides.

Sans contrat de méthode

Private Function CompterCaracteres(ByVal chaine As String) As Integer

Dim resultat As Integer
resultat = chaine.Length

Return resultat

End Function

Ici Refactor ajoute une vérification pour tester la valeur du paramètre, et si jamais celui-ci est nul alors il lui attribue la valeur 0.

Avec contrat de méthode

Private Function CompterCaracteres(ByVal chaine As String) As Integer

Dim lResult As Integer = 0
If chaine Is Nothing Then
Return lResult
End If

Dim resultat As Integer
resultat = chaine.Length

Return resultat

End Function

Utiliser String.Format : Convertit une expression de chaîne composée en un appel unique à String.Format.

Sans utilisation de String.Format

Private Sub AfficheTexte()

Dim monTexte As String
monTexte = "Bienvenue sur " & "Developpez.com le " & Date.Now.ToShortDateString

End Sub

Avec utilisation de String.Format

Private Sub AfficheTexte()

Dim monTexte As String
monTexte = String.Format("Bienvenue sur Developpez.com le {0}", Date.Now.ToShortDateString)

End Sub

Renommer la locale : Renomme la variable locale actuelle et met à jour ses références.

Avant renommage de la variable locale

Private Function CalculPrix(ByVal prix As Integer, ByVal quantite As Integer) As Integer

Dim resultat As Integer

resultat = prix * quantite

Return resultat

End Function

Renommer la variable locale

Après renommage de la variable locale

Private Function CalculPrix(ByVal prixUnit As Integer, ByVal qte As Integer) As Integer

Dim resultat As Integer

resultat = prixUnit * qte

Return resultat

End Function

Changement de nom sécurisé : Change de façon sécurisée le nom des méthodes et propriétés non privées. L'ancien membre est marqué comme étant obsolète.

Avant changement de nom sécurisé

Private _maVariable As String = STR_Developpezcom

Public Property MaVariable() As String
Get
Return _maVariable
End Get
Set(ByVal value As String)
_maVariable = value
End Set
End Property

Après changement de nom sécurisé

Private _maVariable As String = STR_Developpezcom

'
<Obsolete("Use MaNouvelleVariable instead."), _
EditorBrowsable(EditorBrowsableState.Never)> _
Public Property MaVariable() As String
Get
Return MaNouvelleVariable
End Get
Set(ByVal value As String)
MaNouvelleVariable = value
End Set
End Property

Public Property MaNouvelleVariable() As String
Get
Return _maVariable
End Get
Set(ByVal value As String)
_maVariable = value
End Set
End Property

2-3 - Pour aller plus loin

Je ne sais pas si l'on peut réellement parler de bug, plutôt que de défaut de conception, mais toujours est-il que le petit tableau listant les raccourcis clavier disponibles lors de l'emploi d'une fonctionnalité de refactoring, disparait "définitivement" si l'on clique sur la croix rouge dans son coin supérieur droit. En effet, il n'existe pas de moyen conventionnel de les réactiver par la suite. Cependant il existe une parade pour corriger cela, voilà comment procéder :

- Ouvrir le fichier C:\Documents and Settings\[Votre_User]\Application Data\CodeRush for VS .NET\1.1\Settings\Hinting\Shortcuts.ini

- Effacer toutes les lignes se trouvant dans la section [Suppress], ou du moins celles dont vous voulez réactiver le tableau comportant les raccourcis clavier.

Autre astuce que l'on trouve en cherchant bien dans le support de Developer Express est la possibilité de réactiver un menu permettant de configurer de nombreuses options de Refactor. Pour cela il faut intervenir au niveau de la base de registre. Je ne vous donne pas la procédure ici, mais sachez que vous pouvez la trouvez sur le newsgroup de support de Developer Express. Modalités d'accès au newsgroup ici.

Ressources

Refactor pour Visual Basic .NET 2005
Developper Express

Mon blog
Mes articles
Les articles des autres rédacteurs
La rubrique .Net de Developpez.com
La rubrique Sécurité de Developpez.com

Conclusion

J'espère au travers de cet article vous avoir fait découvrir un outil très pratique, et nouveau pour Visual Basic .Net, du moins intégré à Visual Studio et surtout gratuit ! Il n'en existait jusqu'içi aucun à ma connaissance. Certes cet outil n'est pas le plus complet du marché, il propose d'ailleurs moitié moins de fonctionnalités que le même outil en version Pro, payante. Cependant je dois dire que ce Refactor m'a très agréablement surpris, c'est d'ailleurs pour cela que j'ai à l'origine décidé de rédiger cet article. Il n'est certes pas exempt de tout reproche, mais sa réactivité, son ergonomie et sa simplicité d'utilisation, en font selon moi un outil indispensable de tout développeur VB .Net !

Jusqu'à la sortie de Refactor de nombreuses critiques étaient émises quand à l'absence d'un outil de refactoring pour les développeurs utilisant Visual Basic .Net, je pense que Microsoft a su écouter les utilisateurs et a correctement réagi en dotant Visual Basic 2005 de fonctionnalités que son homologue C# possède également. Refactor, un outil à posséder absolument ! Je vous donne rendez-vous très prochainement pour un nouvel article.