Adoptez les instructions de garde et arrêtez d'utiliser des expressions conditionnelles imbriquées !

Prenez l'habitude d'écrire ensemble ! C'est le sixième jour de ma participation au "Nuggets Daily New Plan · April Update Challenge", cliquez pour voir les détails de l'événement .

motivation

Les expressions conditionnelles se présentent généralement sous deux formes :

  • Les deux branches conditionnelles sont un comportement normal
  • Une seule branche conditionnelle est un comportement normal, l'autre branche est anormale

Ces deux types d'expressions conditionnelles ont des objectifs différents, qui doivent être affichés dans le code :

  • Si les deux branches ont un comportement normal, une expression conditionnelle de la forme if...else... doit être utilisée

  • Si une condition est extrêmement rare, elle doit être vérifiée séparément et renvoyée par la fonction dès que la condition est vraie

    Ces contrôles séparés sont souvent appelés "clauses de garde"

L'essence du remplacement des expressions conditionnelles imbriquées par des gardes est d'accorder une attention particulière à une branche. Si vous utilisez une construction if-then-else, vous accordez un poids égal à la branche if et à la branche else. Le message au lecteur d'une telle structure de code est que chaque branche a la même importance. L'instruction de garde indique au lecteur : "Cette situation n'est pas ce dont la logique de base de cette fonction se soucie. Si cela se produit, veuillez effectuer le nettoyage nécessaire et quitter."

L'idée que "chaque fonction ne peut avoir qu'une seule entrée et une seule sortie" est profondément enracinée chez certains programmeurs. Lorsque je travaille avec le code qu'ils écrivent, j'ai souvent besoin d'utiliser des instructions de garde au lieu d'expressions conditionnelles imbriquées. Les langages de programmation d'aujourd'hui n'imposent qu'une seule entrée par fonction, et la règle de "sortie unique" n'est pas très utile. Garder le code clair est la clé : si une seule sortie rend la fonction plus lisible, utilisez une seule sortie ; sinon, ce n'est pas le cas.

entraine toi

Sélectionnez la logique conditionnelle la plus externe qui doit être remplacée et remplacez-la par une instruction de garde.

test.

Si nécessaire, répétez les étapes ci-dessus.

Si toutes les instructions de garde produisent le même résultat, vous pouvez les combiner à l'aide de [Fusionner les expressions conditionnelles].

Cas

Calculer les salaires à verser aux employés. Seuls les employés qui travaillent encore dans l'entreprise doivent être payés, donc cette lettre

Le numéro doit vérifier deux situations «l'employé n'est plus au travail».

    public Long payAmount(Employee employee) {
        long result;
        if (employee.isSeparated) {
            result = 0;
        } else {
            if (employee.isRetired) {
                result = 0;
            } else {
                // logic to compute amount
                lorem.ipsum(dolor.sitAmet);
                consectetur(adipiscing).elit();
                sed.do.eiusmod = tempor.incididunt.ut(labore) && dolore(magna.aliqua);
                ut.enim.ad(minim.veniam);
                result = someFinalComputation();
            }
        } return result;
    }
复制代码

La logique conditionnelle imbriquée rend difficile de voir ce que le code signifie vraiment. Ce n'est que lorsqu'aucune des deux expressions conditionnelles actuelles n'est vraie que ce code commence réellement son travail principal. Par conséquent, les instructions de garde permettent au code d'exprimer sa signification plus clairement

image. Comme toujours, j'aime faire des petits pas, donc je m'occupe d'abord de la logique conditionnelle supérieure.

    public Long payAmount(Employee employee) {
        long result;
        if (employee.isSeparated) {
            result = 0;
        }
        if (employee.isRetired) {
            result = 0;
        } else { // logic to compute amount
            lorem.ipsum(dolor.sitAmet);
            consectetur(adipiscing).elit();
            sed.do.eiusmod = tempor.incididunt.ut(labore) && dolore(magna.aliqua);
            ut.enim.ad(minim.veniam);
            result = someFinalComputation();
        } return result;
    }
复制代码

Après avoir effectué cette modification, j'exécute le test et passe à l'étape suivante.

    public Long payAmount(Employee employee) {
        long result;
        if (employee.isSeparated) {
            return 0l;
        }
        if (employee.isRetired) {
            return 0l;
        }

        lorem.ipsum(dolor.sitAmet);
        consectetur(adipiscing).elit();
        sed. do.eiusmod = tempor.incididunt.ut(labore) && dolore(magna.aliqua);
        ut.enim.ad(minim.veniam);
        result = someFinalComputation();
        return result;
    }
复制代码

À ce stade, la variable de résultat est inutile, je la supprime donc :

    public Long payAmount(Employee employee) {
        if (employee.isSeparated) {
            return 0l;
        }
        if (employee.isRetired) {
            return 0l;
        }
        lorem.ipsum(dolor.sitAmet);
        consectetur(adipiscing).elit();
        sed. do.eiusmod = tempor.incididunt.ut(labore) && dolore(magna.aliqua);
        ut.enim.ad(minim.veniam);
        return someFinalComputation();
    }
复制代码

Il est toujours bon de pouvoir réduire une variable mutable.

inverser la condition

Nous pouvons souvent inverser l'expression conditionnelle pour remplacer les expressions conditionnelles imbriquées par des gardes.

public int adjustedCapital(Instrument anInstrument) {
  int result = 0;
  if (anInstrument.capital > 0) {
    if (anInstrument.interestRate > 0 && anInstrument.duration > 0) {
      result = (anInstrument.income / anInstrument.duration) * anInstrument.adjustmentFactor;
    }
  }
  return result;
}
复制代码

Remplacez un par un. Mais cette fois lors de l'insertion de l'instruction de garde, je dois inverser la condition correspondante :

public int adjustedCapital(Instrument anInstrument) {
  int result = 0;
  if (anInstrument.capital <= 0) {
    return result;
  }
  if (anInstrument.interestRate > 0 && anInstrument.duration > 0) {
    result = (anInstrument.income / anInstrument.duration) * anInstrument.adjustmentFactor;
  }
  return result;
}
复制代码

La condition suivante est un peu plus compliquée, je fais donc l'inversion en deux temps. Ajoutez d'abord une opération NON logique :

public int adjustedCapital(Instrument anInstrument) {
  int result = 0;
  if (anInstrument.capital <= 0) {
    return result;
  }
  if (!(anInstrument.interestRate > 0 && anInstrument.duration > 0)) {
    return result;
  }
  result = (anInstrument.income / anInstrument.duration) * anInstrument.adjustmentFactor;
  return result;
}
复制代码

Mais laisser un NON logique dans une expression conditionnelle comme celle-ci me bousillerait la tête, alors je l'ai simplifié en :

public int adjustedCapital(Instrument anInstrument) {
  int result = 0;
  if (anInstrument.capital <= 0) {
    return result;
  }
  if (anInstrument.interestRate <= 0 || anInstrument.duration <= 0) {
    return result;
  }
  result = (anInstrument.income / anInstrument.duration) * anInstrument.adjustmentFactor;
  return result;
}
复制代码

Ces deux lignes de logique produisent le même résultat, je peux donc les combiner avec [Merge Conditional Expressions] :

public int adjustedCapital(Instrument anInstrument) {
  int result = 0;
  if (anInstrument.capital <= 0 || anInstrument.interestRate <= 0 || anInstrument.duration <= 0) {
    return result;
  }
  result = (anInstrument.income / anInstrument.duration) * anInstrument.adjustmentFactor;
  return result;
}
复制代码

À ce stade, la variable de résultat fait deux choses : d'abord, je la définis sur 0, qui représente la valeur de retour lorsque l'instruction de garde est déclenchée ; puis je lui attribue le résultat du calcul final. Je peux supprimer complètement cette variable, éviter la double responsabilité avec une variable et réduire une autre variable variable.

public int adjustedCapital(Instrument anInstrument) {
  if (anInstrument.capital <= 0 || anInstrument.interestRate <= 0 || anInstrument.duration <= 0) {
    return 0;
  }
  return (anInstrument.income / anInstrument.duration) * anInstrument.adjustmentFactor;
}
复制代码

faire référence à

  • "Reconstruction"
  • "Architecture propre"

Je suppose que tu aimes

Origine juejin.im/post/7083509863132692494
conseillé
Classement