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

12

J'écris une candidature et j'en suis arrivé à ce point:

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

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

private void GiveApples()
{
    ...
}

private void GiveBananas()
{
    ...
}

Cela semble assez simple. Il existe certaines conditions et si elles sont vraies, les méthodes sont appelées. Cependant, je pensais, est-il préférable de faire comme ceci:

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 GiveApplesou GiveBananasest appelée de l'extérieur SomeMethod, elles ne seront exécutées que si elles ont le bon indicateur dans Paramètres.

Est-ce quelque chose que je devrais réellement 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.

Nikola
la source
5
Cela dépend si vous pourriez avoir besoin d'appeler GiveApples ou GiveBananas sans vérifier d'abord. Puisque le gardien est associé à la méthode, il appartient probablement à la méthode.
Robert Harvey

Réponses:

13

Je pense aux gardes comme à quoi la méthode doit obéir. Dans votre exemple, la méthode ne doit pas donner de pommes si Settings.GiveApples est faux.

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

D'un autre côté, si les paramètres ne s'appliquent qu'à la méthode d'appel, et qu'une autre méthode ailleurs dans votre code peut GiveApples quel que soit le paramètre, ce n'est pas un garde et devrait probablement être dans le code d'appel.

Jeremy Hutchinson
la source
5

Placez le garde dans la méthode elle-même. Le consommateur GiveApples()ou GiveBananas()ne devrait pas être responsable de la gestion des gardes de GiveApples().

Du point de vue de la conception, il SomeMethod()faut seulement savoir qu'il a besoin de fruits et ne pas se soucier de ce que votre application doit faire pour l'obtenir. L'abstraction de la récupération des fruits devient fuyante s'il SomeMethod()est responsable de savoir qu'il existe un cadre mondial qui permet la récupération de certains fruits. Cela tombe en cas de changement de votre mécanisme de garde, comme maintenant toutes les méthodes qui doivent GetApples()ou GetBananas()doivent être refactorisées séparément pour implémenter cette nouvelle garde. Il est également très facile d'essayer de perdre des fruits sans cette vérification pendant que vous écrivez du code.

Dans ce scénario, vous devez prendre en compte la réaction de votre application lorsque les paramètres ne permettent pas à votre application de porter ses fruits.

ravibhagw
la source
4

Généralement, c'est souvent une bonne idée de séparer les responsabilités de tester quelque chose comme les paramètres fournis en externe et le "code des activités principales" comme GiveApples. D'un autre côté, avoir des fonctions qui regroupent ce qui appartient ensemble est également une bonne idée. Vous pouvez atteindre ces deux objectifs en refactorisant votre code comme ceci:

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 GiveAppleset / ou GiveBananasdans un endroit séparé sans aucune dépendance de la Settingsclasse. C'est évidemment bénéfique lorsque vous voulez appeler ces méthodes dans un test unitaire qui ne se soucie d'aucune Settings.

Cependant, s'il est toujours erroné dans votre programme, en toutes circonstances, même dans un contexte de test, d'appeler quelque chose comme en GiveApplesdehors d'un contexte où Settings.GiveApplesest vérifié en premier, et vous avez l'impression de fournir simplement une fonction comme GiveApplessans la Settingsvérification est sujette aux erreurs , puis respectez la variante dans laquelle vous testez à l' Settings.GiveApplesintérieur de GiveApples.

Doc Brown
la source