web-dev-qa-db-fra.com

Est-il préférable de protéger l'appel de la méthode ou la méthode elle-même?

J'écris une demande et je suis arrivé à ce point:

private void SomeMethod()
{
    if (Settings.GiveApples)
    {
        GiveApples();
    }

    if (Settings.GiveBananas)
    {
        GiveBananas();
    }
}

private void GiveApples()
{
    ...
}

private void GiveBananas()
{
    ...
}

Cela a l'air assez simple. Il y a des conditions et si elles sont vraies, les méthodes sont appelées. Cependant, je pensais, est-ce plutôt préférable de faire comme ça:

private void SomeMethod()
{
    GiveApples();
    GiveBananas();
}

private void GiveApples()
{
    if (!Settings.GiveApples)
    {
        return;
    }

    ...
}

private void GiveBananas()
{
    if (!Settings.GiveBananas)
    {
        return;
    }

    ...
}

Dans le second cas, chacune des méthodes se garde, donc même si l'une de ces méthodes GiveApples ou GiveBananas est appelée de l'extérieur SomeMethod, ils vont être exécutés uniquement S'ils ont le drapeau correct dans les paramètres.

Est-ce quelque chose que je devrais vraiment considérer comme un problème?

Dans mon contexte actuel, il est très peu probable que ces deux méthodes soient appelées de l'extérieur de cette méthode, mais personne ne peut jamais garantir cela.

12
Nikola

Je pense aux gardes comme quelque chose que la méthode doit obéir. Dans votre exemple, la méthode ne doit pas donner aux pommes si les paramètres.givages sont faux.

Si tel est le cas, le garde appartient certainement à l'intérieur de la méthode. Cela vous empêche de l'appeler accidentellement d'un autre point de votre application sans vérifier les gardes d'abord.

D'autre part, si les réglages s'appliquent uniquement à la méthode d'appel, et une autre méthode ailleurs dans votre code peut contenir des gants quel que soit le paramètre, ce n'est pas un garde et devrait probablement être dans le code d'appel.

13
Jeremy Hutchinson

Généralement, il est souvent judicieux de séparer les responsabilités de tester quelque chose comme des paramètres fournis de manière externe et du "code de base des entreprises" comme GiveApples. D'autre part, avoir des fonctions qui se réunissent ensemble ce qui appartient ensemble est également une bonne idée. Vous pouvez accomplir les deux objectifs en refactorisant votre code comme celui-ci:

private void SomeMethod()
{
    GiveApplesIfActivated();
    GiveBananasIfActivated();
}

private void GiveApplesIfActivated()
{
    if (Settings.GiveApples)
    {
        GiveApples();
    }
}

private void GiveBananasIfActivated()
{
    if (Settings.GiveBananas)
    {
        GiveBananas();
    }
}

private void GiveApples()
{
    ...
}

private void GiveBananas()
{
    ...
}

Cela vous donne une meilleure chance de refactoriser le code de GiveApples et/ou GiveBananas dans un endroit séparé sans dépendances de la classe Settings. C'est évidemment bénéfique lorsque vous souhaitez appeler ces méthodes dans un test unitaire qui ne se préoccupe pas de Settings.

Cependant, s'il est toujours faux de votre programme, dans une circonstance, même dans un contexte de test, appeler quelque chose comme GiveApples en dehors d'un contexte où Settings.GiveApples est cochée en premier et vous êtes sous l'impression de fournir simplement une fonction comme GiveApples sans la vérification Settings est sujette à l'erreur, puis collez-la à la variante où vous testez Settings.GiveApples à l'intérieur de GiveApples.

4
Doc Brown