É melhor proteger a chamada do método ou o próprio método?


12

Estou escrevendo um aplicativo e cheguei a este ponto:

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

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

private void GiveApples()
{
    ...
}

private void GiveBananas()
{
    ...
}

Isso parece bem direto. Existem algumas condições e, se forem verdadeiras, os métodos estão sendo chamados. No entanto, eu estava pensando, é melhor fazer assim:

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

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

    ...
}

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

    ...
}

No segundo caso, cada um dos métodos se protege, portanto, mesmo se algum desses métodos GiveApplesou GiveBananasfor chamado de fora SomeMethod, eles serão executados apenas se tiverem o sinalizador correto em Configurações.

Isso é algo que eu realmente deveria considerar um problema?

No meu contexto atual, é muito improvável que esses dois métodos sejam chamados de fora desse método, mas ninguém pode garantir isso.


5
Depende se você precisar chamar a GiveApples ou a GiveBananas sem verificar primeiro. Como o guarda está associado ao método, provavelmente pertence ao método.
Robert Harvey

Respostas:


13

Penso nos guardas como algo que o método deve obedecer. No seu exemplo, o método não deve fornecer maçãs se Settings.GiveApples for false.

Se for esse o caso, o guarda definitivamente pertence ao método. Isso evita que você o chame acidentalmente de outro ponto do seu aplicativo sem verificar primeiro os guardas.

Por outro lado, se as configurações se aplicarem apenas ao método de chamada, e outro método em outro lugar no seu código puder GiveApples, independentemente da configuração, não é um resguardo e provavelmente deve estar no código de chamada.


5

Coloque a proteção dentro do próprio método. O consumidor GiveApples()ou GiveBananas()não deve ser responsável por gerenciar os guardas de GiveApples().

Do ponto de vista do design, você SomeMethod()deve saber apenas que precisa de frutas e não deve se preocupar com o que seu aplicativo precisa fazer para obtê-lo. A abstração da recuperação de frutas torna-se infiltrada se SomeMethod()for responsável por saber que existe um cenário global que permite a recuperação de determinadas frutas. Isso ocorre em cascata, se o mecanismo de proteção mudar, como agora todos os métodos que precisam GetApples()ou GetBananas()precisam ser refatorados separadamente para implementar essa nova proteção. Também é muito fácil tentar obter frutas sem essa verificação enquanto você escreve código.

O que você deve considerar nesse cenário é como o aplicativo deve reagir quando o Settings não permite que o aplicativo dê frutos.


4

Geralmente, geralmente é uma boa ideia separar as responsabilidades de testar algo como configurações fornecidas externamente e o "código principal de negócios" GiveApples. Por outro lado, ter funções que agrupem o que pertence, também é uma boa idéia. Você pode realizar os dois objetivos refatorando seu código da seguinte maneira:

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()
{
    ...
}

Isso oferece uma chance melhor de refatorar o código GiveApplese / ou GiveBananaspara um local separado sem nenhuma dependência da Settingsclasse. Isso é obviamente benéfico quando você deseja chamar esses métodos em um teste de unidade que não se importa com nenhum Settings.

No entanto, se sempre estiver errado no seu programa, sob qualquer circunstância, mesmo em um contexto de teste, chamar algo como GiveApplesfora de um contexto onde Settings.GiveApplesé verificado primeiro e você tiver a impressão de que apenas fornecer uma função como GiveApplessem a Settingsverificação está sujeita a erros , mantenha-se na variante em que você testa Settings.GiveApplesdentro GiveApples.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.