Quando tenho muitos dados que precisam ser validados, devo criar uma nova classe com o único objetivo de validação ou devo continuar com a validação no método?
Meu exemplo particular contempla um torneio e uma classe de evento / categoria: Tournament
e Event
, que modela um torneio esportivo e cada torneio possui uma ou várias categorias.
Há todo tipo de coisa para validar nessas classes: os jogadores devem estar vazios, devem ser únicos, o número de partidas que cada jogador deve jogar, o número de jogadores que cada partida tem, partidas predefinidas e um grande número de itens, incluindo muito mais regras complexas.
Também há algumas partes que preciso validar como um todo, como a forma como as classes se integram. Por exemplo, a validação unitária de a Player
pode ser ótima, mas se um evento tiver o mesmo jogador duas vezes, isso é um erro de validação.
Então, e quanto a isso ?: Eu esqueço absolutamente qualquer pré-verificação ao usar os setters e métodos semelhantes das minhas classes de modelo para adicionar dados e, em vez disso, deixo as classes de validação lidar com isso.
Portanto, teremos algo como EventValidator
com Event
como membro e um validate()
método que valida todo o objeto, além de métodos singulares para validar as regras de todos os membros.
Então, antes de instanciar um objeto validável, executarei a validação para evitar valores ilegais.
Meu design está correto? Devo fazer algo diferente?
Além disso, devo usar métodos de validação de retorno booleano? Ou apenas lançar uma exceção se a validação falhar? Parece-me que a melhor opção seria retornar métodos booleanos e lançar a exceção quando o objeto é instanciado instantaneamente, por exemplo:
public Event() {
EventValidator eventValidator = new EventValidator(this);
if (!eventValidator.validate()) {
// show error messages with methods defined in the validator
throw new Exception(); // what type of exception would be best? should I create custom ones?
}
}
fonte
Validator
ou dentroValidable
? E como posso trabalhar essas mensagens em conjunto com oValidationException
?Validatable
seja um nome muito melhor doValidable
que o verdadeiro adjetivo #Esse é o problema. Idealmente, você deve impedir que seus objetos tenham um estado inválido: não permita instanciação com estado inválido e se você precisar de setters e outros métodos de alteração de estado, lance uma exceção ali.
Isto não é contraditório. Se a lógica de validação for suficientemente complexa para garantir sua própria classe, você ainda poderá delegar a validação. E se eu entendi que você está correto, é exatamente isso que você está fazendo agora:
Se você ainda possui setters que podem resultar em um estado inválido, valide antes de alterar o estado. Caso contrário, você receberá uma mensagem de erro, mas ainda assim deixará seu objeto com um estado inválido. Novamente: impeça que seus objetos tenham estado inválido
Parece bom para mim, como o validador espera entrada válida ou inválida, portanto, de sua perspectiva, a entrada inválida não é uma exceção.
Atualização: Se "o sistema como um todo" se tornar inválido, o motivo é que algum objeto deve ter sido alterado (por exemplo, um jogador) e algum objeto de nível mais alto (por exemplo, um evento) que faça referência a esse objeto tem uma condição que não é mais cumprida . Agora, uma solução seria não permitir mudanças diretas no player que poderiam invalidar algo em um nível superior. É aqui que os objetos imutáveis ajudam. Então um jogador alterado é um objeto diferente. Depois que um jogador estiver associado a um evento, você poderá alterá-lo apenas do próprio evento (porque precisará alterar a referência para um novo objeto) e validar novamente imediatamente.
fonte