Como se chama essa técnica de programação?

13

Eu me deparei com essa técnica de programação enquanto fazia programação em pares em uma entrevista e não conseguia encontrar o nome dela no google.

A idéia é que você primeiro escreva a expressão que usa as variáveis ​​e depois escreva o código que calcula as variáveis ​​posteriormente.

Para usar algum código de exemplo aqui:

private bool ValidPolicyNumber(string policyNumber) 
{
    var hasExpectedPrefix = policyNumber.Substring(0,5) == "POLIC";
    var followedBy7Digits = Regex.IsMatch(policyNumber.Substring(6,7), "^[0-9]{7}$");
    var hasLengthOf12 = policyNumber.Length == 12;

    return hasExpectedPrefix && followedBy7Digits && hasLengthOf12;
}

Ao escrever esta função usando a técnica que eu mencionei, você primeiro escreveria a última linha return hasExpectedPrefix && followedBy7Digits && hasLengthOf12;e depois as 3 linhas que a precedem.

A técnica mais próxima que pude encontrar é o "pensamento positivo", que é do SICP, mas está relacionado à chamada de funções que você implementará mais tarde, em vez de usar variáveis ​​que você inicializará mais tarde.

user2108462
fonte
8
Acredito que isso seja apenas uma forma de design de cima para baixo .
18717 Vincent Vincentardard
1
Não conheço um nome específico para ele, mas já o vi com bastante frequência quando um conjunto complexo de condições precisa ser verificado. Essa técnica facilita muito a leitura e a compreensão de condições complexas.
FrustratedWithFormsDesigner
Eu fiz isso. Você usa o código para esboçar uma ideia sem suar os detalhes primeiro. Posteriormente, o IDE reclama que algo não existe, então você o faz existir. Ajuda quando você tem um teste que falhará até chegar ao final.
Candied_orange #
Se isso fosse precedido por um teste de unidade, seria Desenvolvimento Orientado a Testes. Ao usar o TDD, conheço meu resultado esperado e trabalho de trás para frente com esse comportamento esperado.
Martin Spamer
Eu chamaria isso de "escrever condições complexas de maneira sadia".
Jimmy Breck-McKye

Respostas:

13

É apenas uma variação na composição funcional.

Testemunha:

private bool ValidPolicyNumber(string policyNumber) 
{
    return hasExpectedPrefix(policyNumber) 
        && followedBy7Digits(policyNumber) 
        && hasLengthOf12(policyNumber);
}

private bool hasExpectedPrefix(string policyNumber)
{
    return policyNumber.Substring(0,5) == "POLIC";
}

private bool followedBy7Digits
{
    return Regex.IsMatch(policyNumber.Substring(6,7), "^[0-9]{7}$");
}

private bool hasLengthOf12
{
    return policyNumber.Length == 12;
}

A única diferença real é que sua versão combina os resultados calculados das funções menores em um único escopo funcional, que é o que você deseja, a menos que as expressões funcionais menores sejam reutilizadas em outros lugares.

Robert Harvey
fonte
9

Isso poderia ser apenas uma sugestão do Clean Code (o livro), a ser usada quando a Decomposição Funcional (como Robert explicou) não for aplicável devido às funções resultantes não serem reutilizáveis ​​por si próprias.

No entanto, se você quiser ser técnico, o livro Implementation Patterns , de Kent Beck, nomeia essa técnica como Explaining Local Variables (ênfase minha):

Variável local

Variáveis ​​locais são acessíveis apenas do ponto de declaração até o final de seu escopo. Seguindo o princípio de que as informações devem se espalhar o menos possível, declare as variáveis ​​locais imediatamente antes de serem usadas e no escopo mais interno possível.

Existem várias funções comuns para variáveis ​​locais:

  • Coletor: uma variável que coleta informações para uso posterior. Frequentemente, o conteúdo dos coletores é retornado como o valor de uma função. Quando um coletor for retornado, nomeie-o como resultado ou resultados.

  • Contagem: um coletor especial que coleta a contagem de alguns outros objetos.

  • Explicando: se você tem uma expressão complicada, atribuir bits da expressão a variáveis ​​locais pode ajudar os leitores a navegar na complexidade:

    int top = ...;

    int esquerda = ...;

    int altura = ...;

    int bottom = ...;

    retornar novo retângulo (superior, esquerdo, altura, largura);

    Embora não seja computacionalmente necessário, as variáveis ​​locais explicativas ajudam o que de outra forma seria uma expressão longa e complicada.

MichelHenrich
fonte