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.

.Net

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.

Installation de Refactor

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 à l'action dans Visual Studio 2005
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
Réordonner les paramètres


barre


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.


barre


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
Sélectionnez

    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
Sélectionnez

    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.


barre


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 :

Surcharge de méthode

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
Sélectionnez

	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


barre


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é
Sélectionnez

    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é
Sélectionnez

    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


barre


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
Sélectionnez

    Private Sub AfficheTexte()
        Me.Label1.Text = "Developpez.com"
    End Sub
Après ajout d'une variable locale
Après ajout d'une variable locale


barre


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
Sélectionnez

    Private Sub AfficheTexte()
        Dim monTexte As String = "Developpez.com"
        Me.Label1.Text = monTexte
    End Sub
Après refactoring
Sélectionnez

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


barre


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
Sélectionnez

    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
Sélectionnez

    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


barre


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
Sélectionnez

        Dim maVariable As String
        maVariable = "Developpez.com"
Après déplacement de l'initialisation
Sélectionnez

        Dim maVariable As String = "Developpez.com"


barre


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
Sélectionnez

        Dim maVariable As String = "Developpez.com"
Après refactoring
Sélectionnez

        Dim maVariable As String
        maVariable = "Developpez.com"


barre


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
Sélectionnez

    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
Sélectionnez

    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


barre


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

Avant inversemment de la condition
Sélectionnez

        If a > 50 Then
            Return True
        Else
            Return False
        End If
Après inversemment de la condition
Sélectionnez

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


barre


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

Avant simplication de l'expression
Sélectionnez

    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
Sélectionnez

    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


barre


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
Sélectionnez

    Dim maVariable As String = "Developpez.com"
Avec constante
Sélectionnez

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


barre


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
Sélectionnez

    Private maVariable As String = "Developpez.com"
Champ après encapsulation
Sélectionnez

    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
Sélectionnez

    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
Sélectionnez

    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


barre


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

Sans utilisation de String.Format
Sélectionnez

    Private Sub AfficheTexte()

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

    End Sub
Avec utilisation de String.Format
Sélectionnez

    Private Sub AfficheTexte()

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

    End Sub


barre


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

Avant renommage de la variable locale
Sélectionnez

    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
Renommer la variable locale


Après renommage de la variable locale
Sélectionnez

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

        Dim resultat As Integer

        resultat = prixUnit * qte

        Return resultat

    End Function


barre


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é
Sélectionnez

    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é
Sélectionnez

    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

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.