Melhor método de validação de parâmetros de função

5

Eu tenho andado com a ideia de criar meu próprio CMS para a experiência e porque seria divertido usar meu site fora da minha própria base de código.

Uma das decisões que continuo voltando é a melhor maneira de validar parâmetros de entrada para funções.

Isso se refere principalmente a tipos de dados simples, já que a validação de objetos seria um pouco mais complexa.

No começo eu debati a criação de uma convenção de nomenclatura que conteria informações sobre o que os parâmetros deveriam ser (int, string, bool, etc) então eu também imaginei que poderia criar opções para validar. Mas, em seguida, em cada função ainda preciso executar algum tipo de validação de parâmetro que analisa o nome do parâmetro para determinar qual valor pode ser validado em relação a ele, desde que isso seja tratado passando a lista de parâmetros para a função, mas que ainda precisa acontecer e um dos meus objetivos é remover a validação do parâmetro da própria função, para que você possa ter apenas o código de função real que realiza a tarefa desejada sem o código adicional para validação.

Existe alguma maneira boa de lidar com isso, ou é tão baixo que a validação de parâmetros é feita no início da chamada de função, então eu devo continuar fazendo isso.

    
por Aglystas 05.09.2012 / 20:36
fonte

4 respostas

2

As soluções gerais para este problema são o tipo de segurança (para que os valores sejam válidos por construção) e o encapsulamento (para que os valores não possam ser invalidados após a construção). Se suas entradas e saídas tiverem tipos significativos, os construtores desses tipos poderão impor as propriedades desejadas. Se a validação for centralizada, você não precisará repeti-la.

Vamos falar em pseudocódigo por um momento. Como um exemplo planejado, considere uma função area(w, h) que calcula a área de um retângulo. Se você digitar a função como:

int area(int w, int h)

Então não há garantia de que qualquer uma das invariantes seja válida:

  • w e h são comprimentos

  • Sendo comprimentos, eles devem ser não negativos

  • O resultado é uma área

Para impor restrições de entrada, você sempre pode adicionar validação ao corpo da função:

int area(int w, int h) {
    assert(w >= 0);
    assert(h >= 0);
    return w * h;
}

Isso não é apenas complicado, mas continua sendo responsabilidade do chamador validar o resultado. Se usarmos tipos que representam nossas unidades:

Area area(Length w, Length h) {
    return w * h;
}

Então, ninguém pode nos dar um Volume quando esperávamos um Length e, como um comprimento não pode ser negativo, não precisamos verificar isso.

O PHP não impõe os tipos estaticamente, mas você pode impedir a construção de objetos inválidos lançando exceções de construtores que recebem entradas inválidas e usando objetos ou acessos imutáveis para evitar invalidação posterior.

    
por 05.09.2012 / 21:43
fonte
1

Com base no comentário "um dos meus objetivos é remover a validação de parâmetro da própria função para que você possa ter apenas o código de função real que realiza a tarefa pretendida sem o código adicional para validação" , você pode querer olhar para usando AOP para validação do método . Espero que as tecnologias que você está usando possam suportar esse paradigma.

Nesse caso, seu validador seria um aspecto e não poluiria a lógica de negócios de sua função. Isso deve adicionar o benefício de tornar sua lógica de validação prontamente reutilizável e ajudará a suportar testes de unidade.

    
por 05.09.2012 / 20:43
fonte
0

Acho que você poderia usar design por contrato no sentido de que o código do seu CMS não está fazendo muita validação, confiando na entrada da camada externa. A camada externa, no entanto, deve ser estrita, talvez até um pouco paranóica em relação à entrada.

Por camada externa, refiro-me aos pontos de extensão do seu cms, por ex. a classe do controlador que é estendida, os objetos que aceitam a extensão por meio de estratégias ou visitante etc. Claro, como já foi observado, você pode usar AOP (agora está disponível em PHP com "hacks" tipo getDocComment)

É claro que isso pode ser um pouco de engenharia excessiva, mas é o que eu faria.

    
por 05.09.2012 / 20:46
fonte
-1

Bem ... eu criaria uma classe de validador. Todas as entradas do usuário passariam por isso. Se a validação falhar, o código retorna.

Agora, você pode usar uma única interface do Validador e criar regras de validação diferentes ou usar apenas um objeto Validador que conheça todas as regras de validação necessárias.

Do que, quando você tem certeza de que um 'número de telefone' é realmente um 'número' e não um caractere, você chama a função que tem isso como parâmetro.

Funções / métodos geralmente não devem verificar a validade dos parâmetros, no entanto, em algumas situações, você ainda precisará verificar algumas coisas. Se algo der errado com uma função, deve lançar e exceção.

Assim, você filtra a entrada do usuário o mais próximo possível do usuário e, ao contrário, você lança exceções para casos imprevistos o mais profundamente possível em sua lógica.

ATUALIZAÇÃO: Além disso, você pode considerar para implementação o Padrão de Projeto do Observador, ou talvez um Mediador, se necessário.

    
por 05.09.2012 / 22:25
fonte