Reflection para executar metodos em ordem

Bom dia,

meu cenario é, duas classes, A e B, B é filho de A, ambas possuem metodos para validação de determinado objeto que é passado por parametro, como chamar esses metodos na ordem de declaração dos metodos?

Tentei com a lib kiss, porem não funciona quando preciso executar os metodos ancestrais. Temporariamente criei um Qualificador tipado para anotar cada metodo por ordem e dai ordenei a execucao por isso.

Queria uma solução mais estrategica para isso, pois as classes de validação possuem bastantes metodos.

Mais estratégicamente falando, o Java é OO, não é estruturado, então não tente fazer com que ele funcione como tal.
Pra fazer uma gambiarra menos tensa que Reflection, vc pode chamar um método que sequencialmente chama os outros que vc quer.
Exemplo:

 void execSeq() {
   metod1();
   metod2();
   metod3();
}
1 curtida

Não posso fazer desta forma, pois são varias classe para validação, o topico inicial é só um exemplo, teria que aplicar solução mais generica possivel

Apesar da religião puramente OO, Java é multi-paradigma.

Mas tem algo esquisito ai que vai além dessa questão. Por que as validações não estão vinculadas diretamente a cada classe?

As validações são de cada classe, porem tem casos que é necessario aproveitar o metodo do ancestral sem necessidade de duplicação do mesmo

Seu modelo deve estar desnecessariamente complexo pra ficar agora atrás de intervenções cirúrgicas.

Usar reflection afeta a performance, além de ficar como uma solução esquisita para este caso. Se nao pode simplificar seu modelo, faz o que o colega sugeriu, chama os métodos normalmente sob seu controle. Se são “500 classes”, então o problema que são 500 classes. Estranho que você nem deveria estar se preocupando em resolver tudo de uma vez, o ideal é desenvolver de forma incremental, vai incrementando conforme desenvolvimento de cada classe. Você pode até criar futuras armadilhas mágicas, mas não existe solução genérica para o Negocio, os requisitos são dinâmicos e o cliente tem que pagar por cada funcionalidade.

No geral acho que tem algo de complicado sem necessidade nesse seu modelo. Mostra algum exemplo, pois ainda não mostrou na prática. Além disso, principalmente explicar o objetivo real para o usuário. Classes “A e B, B é filho de A”, e “aproveitar o metodo do ancestral sem necessidade de duplicação do mesmo” isso tudo é muito abstrato, além de confuso a ponto de talvez nem ser necessário. O mais importante é partir do requisito que precisa atender e dai poderá ter sugestões para resolver bem o problema como um todo.

Poxa cara, lê de novo a publicação inicial que voce vai entender!

Você só falou questões técnicas, de acordo com um vício de solução. O que precisa resolver de fato pro usuário não. A e B não significam nada de real.

Poderia usar Bean Validation como a maioria usa, ou dizer por que no seu caso não se aplica. Se tem problema em executar as validações fora da “ordem” colocada no código, é porque não está protegendo cada validação. Se prender a ordem dos métodos no código pode levar a acidentes, a manutenção vira um campo minado.

obrigado

A descrição do seu problema ficou muito abstrata.
É estranho você ter que depender da ordem de declaração dos métodos para executá-los.

Não seria melhor implementar o padrão Chain of Responsibility ou de repente um Strategy?

Há algum tempo eu implementei umas classes de validação genéricas que são uma espécie de mistura entre o padrão Builder e Strategy.

Veja no meu GitHub se isso não é mais simples pra resolver seu problema:

Vamos simplificar meu caso, eu quero apenas executar todos metodos de determinada classe em ordem de declaração dos metodos.

OK, mas a documentação não garante que a reflection API fornece os métodos das classes na ordem em que foram declarados.
Se quer realmente continuar com reflection, sugiro que ao menos crie uma anotação para indicar a ordem do método, de forma que consiga via reflection executar na ordem desejada.

1 curtida

Porque não ter um método que invoque os outros pela ordem pretendida?

private void a(){
    ...
}
private void b(){
    ...
}
private void d(){
    ...
}
private void c(){
    ...
}
public void validate(){
    a();
    b();
    super.x(); // Validação no pai
    c();
    d();
}

Desta forma foi feito, queria remover as anotações.

Cada classe tem 100 metodos de validação, teria que chamar 100, não é trivial

O problema todo que esta sua solução está muito ruim, e está querendo deixar cada vez mais bizarro com soluções fora do usual e sem necessidade.

1 curtida

Quem fez dessa forma, já deve ter se ligado que não há garantia de obter os métodos na ordem em que foram declarados.

Eu criaria uma classe para cada validação.
Depois criaria outra classe, com a mesma interface, mas na qual o método de validação delegasse para às outras centenas de classes, na ordem que eu quiser.

Mas esse sou eu, que gosta de código coeso e reaproveitável…

1 curtida

Ou seja, implementar o padrão Observer, mas imagina, fazer a em 200 métodos!? Não seria trivial

Com Bean Validation o problema seria resolvido com uma unica chamada, independente de quantas validações customizadas. Só teria que corrigir o que tem hoje, pelo desleixo em depender da ordem de execução para alguma validação não quebrar, ou sei lá qual motivo que esconde tanto.