2009-10-20 7 views
20

Quelles approches les gens prennent (le cas échéant) dans la gestion guard clause explosion dans vos classes? Par exemple:Refactoring Guard Clauses

public void SomeMethod<T>(string var1, IEnumerable<T> items, int count) 
{ 
    if (string.IsNullOrEmpty(var1)) 
    { 
     throw new ArgumentNullException("var1"); 
    } 

    if (items == null) 
    { 
     throw new ArgumentNullException("items"); 
    } 

    if (count < 1) 
    { 
     throw new ArgumentOutOfRangeException("count"); 
    } 

    ... etc .... 
} 

Dans le projet que je travaille actuellement il y a beaucoup de classes qui ont un ensemble similaire de clauses de garde sur les méthodes publiques. Je connais les contrats de code .NET 4.0, mais ce n'est pas une option pour notre équipe pour le moment.

Répondre

39

beaucoup de projets que je l'ai vu utiliser une classe Guard statique.

public static class Guard { 
    public static void ArgumentIsNotNull(object value, string argument) { 
     if (value == null) 
      throw new ArgumentNullException(argument); 
    } 
} 

Cela rend le code beaucoup plus propre, à mon avis.

Guard.ArgumentIsNotNull(arg1, "arg1"); 
+1

Je venais de poster la même chose. Le seul problème est qu'il met cette méthode en haut de la trace de la pile par rapport à la méthode d'origine en haut, pas que c'est énorme. Ce modèle pourrait évidemment être utilisé pour différents types de vérifier une gamme de valeurs, etc ... –

+0

Ouais, c'est le seul problème que j'ai jamais eu avec elle.Bien qu'il soit assez facile de trouver la méthode d'appel originale. –

+1

Ceci est essentiellement la même chose que les classes qui imitent les contrats de code. –

5

Si vous ne voulez pas aller dans le code la route des contrats, une façon de simplifier est de supprimer les accolades:

public void SomeMethod<T>(string var1, IEnumerable<T> items, int count) 
{ 
    if (string.IsNullOrEmpty(var1)) 
     throw new ArgumentNullException("var1"); 

    if (items == null) 
     throw new ArgumentNullException("items"); 

    if (count < 1) 
     throw new ArgumentOutOfRangeException("count"); 

    ... etc .... 
} 

autres que cela, il y a des façons que vous pouvez simuler Code des marchés , si votre objection est que .Net 4.0 n'est pas encore prime time:

http://geekswithblogs.net/Podwysocki/archive/2008/01/22/118770.aspx

+0

Pour l'amour de Dieu, ne faites pas ça! Si les déclarations sans accolades est un excellent moyen de vous causer des problèmes sur la route. – EricRRichards

+1

@EricRRichards: * [hausser] * Franchement, si les programmeurs ne peuvent pas garder leur code droit sans accolades (en particulier un code banal comme celui-ci), ils devraient probablement retourner à l'école. –

3

Une approche pour réduire (pas tout à fait la suppression) numéro de clauses de garde est de comprendre la cause de leur existence. Très souvent, il s'avère que nous protégeons les valeurs valides pour le type de l'argument, mais pas pour la méthode qui les accepte. En d'autres termes, la méthode est définie sur un sous-ensemble du domaine défini par le type d'argument.

Une solution à cette catégorie de cas consiste à essayer de définir un sous-type (par exemple une interface plus restrictive) et à accepter ce type en tant qu'argument. Vous pouvez trouver un exemple illustratif dans cet article: Why do We Need Guard Clauses?

Bien sûr, cette technique ne s'applique pas à tous les cas. Tous les types de référence autorisent au moins des références nulles. Par conséquent, la plupart de nos méthodes seront définies sur une partie du domaine, ce qui nécessite à son tour une clause de garde contre null. Mais, du point de vue positif, cette technique aide à faire prendre conscience des méthodes qui reçoivent des arguments plus généraux que souhaité. Plomberie ce trou permet d'améliorer la conception en général.