Pergunta

Eu tenho feito uma revisão de código enorme e um padrão que eu notar em todo o lugar é este:

public bool MethodName()
{
    bool returnValue = false;
    if (expression)
    {
        // do something
        returnValue = MethodCall();
    }
    else
    {
        // do something else
        returnValue = Expression;
    }

    return returnValue;
}

Isto não é como eu teria feito isso eu teria acabado de voltar o valor quando eu sabia o que era. qual desses dois padrões é mais correto?

Saliento que a lógica parece sempre ser estruturado de tal forma que o valor de retorno é atribuído em apenas um plave e nenhum código é executado após ser atribuído.

Foi útil?

Solução

Há uma longa discussão sobre este tema aqui .

Outras dicas

Um monte de pessoas recomendo ter apenas um ponto de saída a partir de seus métodos. O padrão que você descreve acima segue essa recomendação.

A principal essência do que a recomendação é que se or têm de limpeza alguma memória ou estadual antes de voltar a partir do método, é melhor ter esse código em um só lugar. ter vários pontos de saída leva a quer a duplicação de código de limpeza ou potenciais problemas devido à falta de código de limpeza em um ou mais dos pontos de saída.

É claro que, se o seu método é par de linhas, ou não precisa de qualquer limpeza, você pode ter vários retornos.

Eu teria ternário usado, para reduzir estruturas de controle ...


return expression ? MethodCall() : Expression;

Eu suspeito que eu vou estar em minoria, mas eu gosto do estilo apresentado no exemplo. É fácil de adicionar uma declaração de registro e definir um ponto de interrupção, IMO. Além disso, quando usado de forma consistente, parece mais fácil de "correspondência de padrões" do que ter vários retornos.

Eu não estou certo que há uma resposta "correta" sobre isso, no entanto.

Alguns institutos de aprendizagem e livros defendem a prática de retorno único.

Se é melhor ou não é subjetiva.

que se parece com uma parte de um projeto ruim OOP. Talvez ele deve ser reformulado no nível mais elevado do que no interior de um único método.

Caso contrário, eu prefiro usar um operador ternário, como este:

return expression ? MethodCall() : Expression;

É mais curto e mais legível.

Retorno de um método de imediato em qualquer uma destas situações:

  1. Você encontrou uma condição de contorno e necessidade de retornar um valor único ou sentinela: if (node.next = null) return NO_VALUE_FOUND;
  2. Um valor exigido / estado é falsa, então o resto do método não se aplica (aka uma cláusula de guarda). Ex .: if (listeners == null) return null;
  3. O método objetivo é encontrar e devolver um valor específico, por exemplo .: if (nodes[i].value == searchValue) return i;
  4. você está em uma cláusula que retorna um valor único a partir do método não é usado em outras partes do método: if (userNameFromDb.equals(SUPER_USER)) return getSuperUserAccount();

Caso contrário, é útil ter apenas uma instrução de retorno de modo que é mais fácil adicionar o registo de depuração, limpeza dos recursos e seguir a lógica. Eu tento lidar com todos os acima de 4 casos em primeiro lugar, que se apliquem, em seguida, declarar uma variável chamada result(s) tão tarde como possíveis valores e atribuir a esse conforme necessário.

Ambos realizar a mesma tarefa. Alguns dizem que um método deve ter apenas uma entrada e uma saída.

Eu uso isso também. A ideia é que os recursos podem ser libertados no fluxo normal do programa. Se você saltar de um método em 20 lugares diferentes, e você precisa chamar a limpeza () antes, você vai ter que acrescentar ainda um outro método de limpeza 20 vezes (ou refactor tudo)

Eu acho que o codificador tomou o design de definir um objeto toReturn no topo do método (por exemplo, List toReturn = new ArrayList ();) e, em seguida, preenchê-lo durante a chamada de método, e de alguma forma decidiu aplicá-lo a um tipo de retorno booleano, o que é estranho.

Também poderia ser um efeito colateral de um padrão de codificação que os estados que você não pode voltar no meio de um corpo de método, apenas no final.

Mesmo se nenhum código é executado após o valor de retorno é atribuído agora não significa que algum código não terá que ser adicionados mais tarde.

Não é o mais pequeno pedaço de código que pode ser usado, mas é muito refatoração de usar.

Delphi obriga este padrão criando automaticamente uma variável chamada "Resultado", que será do tipo de retorno da função. Seja qual for "Resultado" é quando a função sai, é o seu valor de retorno. Então não há nenhuma palavra-chave "retorno" em tudo.

function MethodName : boolean;
begin
  Result := False;
  if Expression then begin
    //do something
    Result := MethodCall;
  end
  else begin
    //do something else
    Result := Expression;
  end;

  //possibly more code
end;

O padrão utilizado é detalhado - mas também é mais fácil de depurar se você quer saber o valor de retorno sem abrir a janela de Registros e verificar EAX

.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top