web-dev-qa-db-fra.com

Nommer les clauses de garde qui jettent des exceptions

J'ai une fonction evaluate() qui analyse A String pour certaines variables et les remplace avec leur valeur correspondante:

public String evaluate() {
    String result = templateText;
    for (Entry<String, String> entry : variables.entrySet()) {
        String regex = "\\$\\{" + entry.getKey() + "\\}";
        result = result.replaceAll(regex, entry.getValue());
    }
    if (result.matches(".*\\$\\{.+\\}.*")) {    //<--check if a variable wasn't replaced
        throw new MissingValueException();
    }
    return result;
}

Depuis la fonction evaluate() fonctionne maintenant 2 choses, il remplace d'abord les variables avec les valeurs [~ # ~ ~] et [~ # ~] Vérifiez que les variables ne sont pas remplacées, j'ai pensé à le refléter à:

public String evaluate() {
    String result = templateText;
    for (Entry<String, String> entry : variables.entrySet()) {
        String regex = "\\$\\{" + entry.getKey() + "\\}";
        result = result.replaceAll(regex, entry.getValue());
    }
    checkForMissingValues(result);
}

private void checkForMissingValues(String result) {
    if (result.matches(".*\\$\\{.+\\}.*")) {
        throw new MissingValueException();
    }
}

C'est un bon nom pour la fonction checkForMissingValues? Je veux dire que cela vérifie les valeurs manquantes, mais elle jette également une exception.

J'ai pensé à le renommer à throwExceptionIfMissingValueWasFound(), mais ce nom indique [~ # ~] Comment [~ # ~] La fonction fait C'est plus que [~ # ~] Qu'est-ce que [~ # ~ ~] La fonction fait.

Existe-t-il une norme pour nommer de telles fonctions qui recherchent une condition alors lancez une exception?

6
Songo

Votre nom de routine me semble parfaitement amende pour moi. Qu'est-ce qui est si mauvais pour "vérifier"?

J'ai tendance à le casser, cependant. J'ai donc une routine qui fait le chèque/le lancer, plus des fonctions qui font les tests réels. Tu serais finir avec quelque chose comme:

check(!hasMissingValues(result));

Cela le rend plus qu'une convention de dénomination. Vous pouvez l'appeler "Valider" ou "Appliquer" ou autre, mais la clé de la clé que check a un comportement défini.

(Cela suppose bien sûr que les types de conditions que vous êtes checking ne nécessite pas de tas d'informations d'exception personnalisées, mais c'est souvent le cas.)

2
jtolle

Je ne pense pas que cela justifie une méthode distincte. J'ai aussi remarqué plusieurs choses:

Vous créez un objet Pattern pour chaque variable dans votre Map. La création d'objets de motif est chère (nécessite un analysement). Vous évaluez ensuite la regex sur la chaîne avec replaceAll. Donc, si vous avez 100 variables qui deviennent 100 regextes analysées et créées, la chaîne est numérisée 100 fois. C'est inefficace.

Votre regex pour numériser les variables manquantes est extrêmement chère. Il scannera chaque personnage de votre chaîne plusieurs fois, surtout s'il contient ${.

Ce que vous devez faire, c'est basculer la logique. Trouver des chaînes ${x} Dans le texte et récupérer des variables de votre carte pour le remplir, jetant une exception la première fois que vous rencontrez une variable manquante.

public String evaluate() {
    Matcher matcher = Pattern.compile("\\$\\{(\\.+?\\)}").matcher(templateText);
    StringBuilder result = new StringBuilder(templateText.length());
    while(matcher.find()) {
        String val = variables.get(matcher.group(1));
        if (val == null) throw new MissingValueException();
        matcher.appendReplacement(result, val);
    }
    matcher.appendTail(result);
    return result.toString();
}

Cela recherchera la chaîne une seule fois avec une seule regex. Cela échouera sur la première variable manquante. Si vous avez 100 variables définies, mais seulement 1 apparaît dans le modèle seulement 1 Remplacer est effectué.

1
Java guy

Tout d'abord, les méthodes de C # suivent la convention Pascal, elle devrait donc être évaluée et ne pas évaluer.

Deuxièmement: il est naturel que les méthodes énoncent des exceptions, des scénarios exceptionnels exceptionnels, de sorte que vous n'avez pas à nommer votre méthode pour la signifier.

Troisièmement: il n'est pas normal de jeter une exception en raison d'une vérification interne (sauf si vous avez un besoin spécifique). Idéalement, la méthode doit renvoyer un BOOL qui indique si le chèque a réussi ou échoué. Donc, la signature de méthode doit idéalement être:

private bool IsMissingValues(String result) 

Ensuite, un nom de méthode n'a pas toujours à expliquer chaque détail de ce qu'il fait, le lisez toujours en conjonction avec la classe dans laquelle il est défini.

D'où, String.Replace est suffisant; String.ReplaceThisStringWithAnother est surchargé.

En parlant de quoi, votre méthode d'évaluation devrait être idéalement appelée Remplacer ou quelque chose comme ça, ce qu'il fait essentiellement.

Les méthodes privées peuvent également être relativement moins "verbeuses" que celles publiques, car personne d'autre sauf que vous le verrez (OK bien, c'est discutable).

0
bobbyalex
public String evaluate() {
    String result = replaceVariablesWithValues();
       // Extract the for loop code to the new method listed above

    if (resultContainsVariables(result)) {    
         // All variables should have been replaced
        throw new MissingValueException();
    }
    return result;
}

Ci-dessus est ma proposition de refacteur.

  1. La fonction d'évaluation proposée décrit succinctement la fonctionnalité générale (remplacer les variables avec des valeurs) ainsi que le boîtier d'exception (si le résultat contient des variables, lancez une exception).
  2. Les détails des évaluations des regex devraient être extraits sur des fonctions d'assistance car il ne faut pas nécessairement pas besoin d'analyser mentalement la regex pour comprendre le contrat et le contrôle des flux d'évaluation. De plus, je suggère de faire le préfixe de regex et le suffixe des constantes.
  3. Je suggère de garder la déclaration de lancer dans l'évaluation. Ce n'est pas évident ce qu'est une fonction "chèque" ou de garde, mais sachant quelle telle fonction est nécessaire pour comprendre le contrat d'évaluation.
0
Aaron Kurtzhals