Dispositivo de validação

 

No presente modelo, uma validação qualquer está definida simplesmente como a execução de uma regra Rule sobre um conjunto qualquer de dados RuleInput, produzindo uma saída RuleOutput, que indica a condição da execução, a saber: sucesso, alerta, erro e erro fatal. Assim, o processador RulesProcessor recebe um conjunto ValidationInputs de entradas e um conjunto ValidationRules de regras, produzindo um conjunto ValidationOutputs como saída da sua execução. Portanto, a utilização do processador requer simplesmente a implementação da interface RuleInput para o encapsulamento do conjunto de dados a serem validados e a implementação da interface Rule para cada regra a ser aplicada a esse conjunto de dados. O design prevê que tanto a lógica de obtenção das regras quanto a de obtenção das entradas resida numa implementação de RulesProcessor, que deve ser registrada por register(), utilizando como argumento um nome arbitrário qualquer. As instâncias da implementação são obtidas, naturalmente, por getInstance().

De modo a evitar que a fábrica RulesProcessor retorne um singleton, o método register() não salva a instância recebida como argumento, mas simplesmente uma template para a criação de novas instâncias, obtida por template.getClass().getCanonicalName(). Assim, getInstance() retorna uma nova instância obtida por Class.forName().newInstance(), o que significa que todas as implementações de RulesProcessor devem requerer não mais que um construtor sem argumentos. De um modo geral, esse é o design utilizado para todas as classes abstratas cujas implementações sejam registradas a partir da configuração do software e cujo projeto não requeira obrigatoriamente um singleton.

Por outro lado, ValidationRules não é simplesmente uma especialização de HashSet, mas também uma abstract factory. Isso foi feito de modo a possibilitar o registro de conveniência de conjuntos específicos de regras de validação, obtidos dinamicamente da configuração e registrados por register. Neste caso e como as regras são fixas e usadas passivamente, ao contrário de eventuais implementações de RulesProcessor, getInstance() retorna um singleton.

O método getInput() da interface RuleInput requer como parâmetro um objeto do tipo da entrada requerida e foi implementado simplesmente para assegurar a possibilidade de mais de um tipo de entrada para a regra de validação. Por outro lado, a interface Rule recebe como parâmetro o conjunto completo de entradas ValidationInputs. Isso significa que a implementação da interface deve ter algum modo de obter sua entrada do parâmetro recebido. Isso foi delegado às diversas implementações de RulesProcessor. O design escolhido foi registrar um set contendo a lista de nomes arbitrárias dos objetos ValidationRules registrados pela configuração e obter esse conjunto sempre que as regras são necessárias. Isso torna o comportamento do software diretamente dependente da estratégia de registro dos seus vários componentes, obtidos do seu repositório de configuração. O método recoverableException() se destina a permitir a tomada de decisão na presença de erros que podem ser recuperados pelo usuário durante a sessão. A idéia é que as implementações devolvam aí uma instância da exceção ocorrida, possivelmente recuperável pela ação do usuário, como, por exemplo, a falta do certificado do assinante.

Por fim, o design prevê, ainda que isto não esteja expresso no modelo, que as implementações de Rule especializem java.lang.Throwable, de modo a poderem ser utilizadas como retorno de RuleOutput.getCause(). Observe-se apenas que o método getSlot() é destinado para a devolução de qualquer dado eventualmente necessário ao processo, para uso por processamento e não por seres humanos.