Invejando descaradamente o conto de cada dia do Phillip
public class ManagedBeanCRUD [E,ID]{
private E instancia;
public E getInstancia(){return instancia;}
public Void setInstancia(E entidade){this.instancia = entidade;}
public String salvar(){
preSalvar();
servicoCrud.salvar(getInstancia);
return "navegacaoListar";
}
public void preSalvar(){}
}
E apartir desse MB crio os meus outros CRUDS simples, exemplo telefone:
public class TelefoneMB extends ManagedBeanCRUD [Telefone, Integer] {
@Override
public void preSalvar(){
System.out.println("Oi esse é gancho ...");
}
}
Ótimo, houve reuso por meio da herança mas logo veio as seguintes perguntas: porque não transformou os métodos preXXX em métodos abstratos? Porque daí eu teria que obrigar o usuário a implementar sempre mesmo quando não fosse necessário. porque não usou composição ao invés da herança? Porque minha visão (xhtml) já está toda padronizada.
[c:campoentrada binding="#{mb.instancia.numero}"/]
[c:botao binding="#{mb.salvar}"/]
Note que o método salvar não existe (ao menos no fonte) na classe TelefoneMB ele é acessado por herança. A primeira tentativa foi substituir a herança por composição por meio de delegação, minha classe TelefoneMB ficaria mais ou menos assim:
public class TelefoneMB{Mas será que não pode ser melhorado?!
private ManagedBeanCRUD[Telefone, Integer] delegate;
public String salvar(){
return delegate.salvar();
}
// + do mesmo
}
Claro que sim até agora consegui chegar num patamar assim: os métodos ganchos se transformam no padrão decorator e a herança se torna composição por delegação mas de um modo diferente, fiz o MangedBeanCRUD ser um atributo de leitura :
public class TelefoneMB{E na view (jsf, xhtml ...) não terei muita mudança será uma navegação a mais na #EL #{telefonemb.crud.salvar} terei que adicionar o crud antes do padrão CRUD de ser.
private ManagedBeanCRUD[Telefone, Integer] crud;
public TelefoneMB(){
crud.addEventoPreSalvar(new Evento(){
public void executar(){
System.out.println("antes de salvar...");
}
});
}
public ManagedBeanCRUD getCrud(){
return crud;
}
}
Com isso tenho um managed bean livre de más práticas, melhorei o sistema de eventos e mais um plus não terei problemas futuros com proxies do JDK ou GLIB2! Mais camadas e indireções sempre foi o caminho conforme post sobre abstrações pra todo lado.
Todo comentário sempre é e será bem-vindo!
ps: só pra deixar claro não sou contra o uso da herança, há casos que você pode usar herança para compor suas entidades e outros n usos. O único cuidado que deve ter é pensar, pensar, pensar e pensar para decidir se é herança ou não.