Eu tenho uma função de verificação de valor, algo semelhante a uma função de verificação de número de cartão de crédito, que é passada em uma string e precisa verificar se o valor está no formato correto.
Se é o formato certo, ele precisa retornar true.
Se não for o formato correto, ele precisará retornar false e também nos informar o que há de errado com o valor.
A questão é: qual é a melhor maneira de conseguir isso?
Aqui estão algumas soluções:
1. Use códigos de retorno inteiro / enum para significar significados:
String[] returnCodeLookup =
[
"Value contains wrong number of characters, should contain 10 characters",
"Value should end with 1",
"Value should be a multiple of 3"
]
private int valueChecker(String value)
{
/*check value*/
return returnCode;
}
rc = checkValue(valueToBeChecked);
if rc == 0
{
/*continue as normal*/
}
else
{
print("Invalid value format: ") + returnCodeLookup[rc];
}
Não gosto dessa solução, pois requer implementação no lado do chamador.
2. Crie uma classe returnCode
Class ReturnCode()
{
private boolean success;
private String message;
public boolean getSuccess()
{
return this.success;
}
public String getMessage()
{
return this.message;
}
}
private ReturnCode valueChecker(String value)
{
/*check value*/
return returnCode;
}
rc = checkValue(valueToBeChecked);
if rc.getSuccess()
{
/*continue as normal*/
}
else
{
print("Invalid value format: ") + rc.getMessage();
}
Esta solução é arrumada, mas parece exagerar / reinventar a roda.
3. Use exceções.
private boolean valueChecker(String value)
{
if int(value)%3 != 0 throw InvalidFormatException("Value should be a multiple of 3";
/*etc*/
return True;
}
try {
rc = checkValue(valueToBeChecked);
}
catch (InvalidFormatException e)
{
print e.toString();
}
Estou tentado a usar esta solução, mas me disseram que você não deve usar exceções para a lógica de negócios.
fonte
Respostas:
Use um objeto de retorno mais complexo que encapsule as duas preocupações. Exemplo:
Isso tem várias vantagens:
Na verdade, já usei esse design específico em aplicativos em que uma validação pode ser mais do que simplesmente verdadeira ou falsa. Talvez seja necessária uma mensagem detalhada ou apenas parte da entrada seja inválida (por exemplo, um formulário com dez elementos pode ter apenas um ou dois campos inválidos). Usando esse design, você pode acomodar facilmente esses requisitos.
fonte
IValidationResult.SUCCESS
que retorne uma mensagem de erro vazia. Então sua lógica é parecida comif (result != SUCCESS) { doStuff(result.getMessage()); }
Nenhuma das opções acima, use uma classe ValueChecker
Primeiro uma interface para oferecer flexibilidade:
Em seguida, implemente quantos avaliadores de valor forem necessários:
Código de cliente de amostra:
Tem a vantagem de poder ter muitos verificadores de valores diferentes.
fonte
Minha resposta estende a abordagem de @ Snowman. Basicamente, toda validação, toda regra de negócios e toda lógica de negócios devem resultar em alguma resposta - pelo menos em aplicativos da web. Essa resposta, por sua vez, é exibida para um chamador. Isso me levou à seguinte interface (é php, mas a questão é agnóstica por natureza):
A criação do operador do switch agindo como uma expressão, não como uma instrução, leva ao serviço de aplicativo assim:
fonte