está o início da discussao, mas nao posso responder por ele ter mais
de 60 dias...patético...isso vai pro quilixo...
Bem...
Hoje apresentando o Merlin no FISL em Porto Alegre, me veio esse
conceito de inferencia de dependencias entre controles de comboboxes e
notei que esse topio esta meio obscuro. Vou explicar melhor, entao:
Segundo a imagem http://groups.google.com/group/treelayer-merlin/web/inferenciaDeDependencias-2007-04-14.JPG
A dependencia inferida é "ao selecionar UF, o controle Cidade é
preenchido com os valores relativos a selecao da UF". Essa dependencia
é inferida pelo link que existe de cidade para UF no modelo de
objetos. Como ambos (cidade e UF) estao sendo colocados na tela do
cadastro, é assumida uma dependencia automatica entre a UF e a cidade.
E, até provem o contrario para mim, essa é uma boa heuristica...
Mas, como essa dependencia poderia ser implementada, ou melhor
dizendo, como preencher as cidades em funcao da UF selecioanda? A
resposta vem novamente do modelo de dados OO. Em outras palavras,
pelas praticas da (nova?) JPA ou do Hibernate, o projetista deve ter
feito uma modelagem onde UF tenha o metodo "getCidades()", pois,
logicamente, UF é uma agrecacao de cidades (...) seja ela LAZY ou nao.
Assim, o Merlin simplesmente invoca o metodo relativo "getCidades()"
para preencher a combo de cidades. Ao invocar o metodo "getCidades", o
retorno (uma colecao de cidades - java.util.Collection<Cidade>) é
tratado automaticamente pelo renderizador associdado padrao, que exibe
(muito provavelmente) o campo "nome" da cidade no texto da combobox.
Se a colecao foi mapeada como LAZY, o suporte de bytecodes engineering
do JPA ou do Hibernate faz o resto para nós, buscando os dados
conforme a necessidade. Se a colecao nao for LAZY, da na mesma, pois
os dados ja estao ali.
E se nao estivermos usando JPA ou Hibernate? A resposta é: Nao
importa, pois como o Merlin é baseado em objetos, o fato de
"getCidades" ter retornado valores do banco ou nao é indiferente. O
que importa é que "getCidades" retorna uma colecao (ou lista -
java.util.List<Cidade>) de cidades. E pronto. All working fines...
Att,
Cabe salientar o seguinte ainda...outra heuristica.
É quase certo que UF vai aparecer antes de Cidade no formulario de
cadastro do cliente. E por que? Porque UF é, em suma, mais importante
que Cidade? Nao exatamente...
O que acontece é que Cidade depende de UF. Assim, é mais ou menos
certo (heuristica) que primeiro o usuario tera que escolher a UF para,
entao, selecionar uma Cidade dessa UF selecionada. Assim, ao
renderizar os controles, é - outra heuristica - que UF aparecera
"antes" na tela.
Mas esse "antes" é subjetivo. Por antes, nós, ocidentais, assumimos
como sendo "acima, a esquerda", que é nosso processo normal de
leitura. Em outras palavras, ao "pegarmos" uma informacao para ler (um
texto ou uma tela de cadastro), nossos olhos, intuitivamente, vao se
posicionar primeiro na parte superior da tela e, pasmem ou nao, na
parte esquerda (...em outras palavras, quando voces querem fechar um
sistema pelo menu...aonde esta o menu File?).
Bem, são essas as heuristicas que, provem o contrario para mim,
indicam com boa seguranca, que UF vira "antes" de Cidade na tela....
Talvez seja por isso que, quando falo que a anotacao @Order do Merlin
é subjetiva, as pessoas parecem nao entender muito bem...
Att,
On Apr 14, 9:25 pm, "Marcelo Mrack" <mmr...@gmail.com> wrote:
> No post
>
> http://groups.google.com/group/treelayer-merlin/browse_thread/thread/...
>
> está o início da discussao, mas nao posso responder por ele ter mais
> de 60 dias...patético...isso vai pro quilixo...
>
> Bem...
>
> Hoje apresentando o Merlin no FISL em Porto Alegre, me veio esse
> conceito de inferencia de dependencias entre controles de comboboxes e
> notei que esse topio esta meio obscuro. Vou explicar melhor, entao:
>
> Segundo a imagemhttp://groups.google.com/group/treelayer-merlin/web/inferenciaDeDepen...
Marcelo o usuário pode ir diretamente ao estado sem escolher o uf primeiro, neste caso o combo nao teria cidades ou teria todas?
Assisti tua palestra no fisl, tava bem legal, já tinha lido sobre as
funcionalidades básicas do Merlin, mas não tinha entendido muito bem o
uso das heurísticas. Falando sobre isso, nesse caso da dependência
entre UF e cidade, por exemplo, essa relação de dependência é um
conhecimento que é adquirido ao longo do tempo, ou seja, depois que a
primeira aplicação for implementada, como esse conhecimento será
armazenado e compartilhado e em que momento isso irá acontecer?
Depois que a aplicação estiver pronta o programador irá gerar um
conjunto de heurísticas dessa aplicação e reutilizar em outras?
Não sei se já tem alguma idéia pronta sobre isso, mas é uma dúvida que
tenho.
On Apr 14, 11:06 pm, "Marcelo Mrack" <mmr...@gmail.com> wrote:
> Oi,
>
> Vc quer dizer...ir diretamente em Cidade, isso ?
>
> Nesse caso, poderia ser listado tudo...mas uma heuristica de performance
> provavelmente vai evitar isso. Para fazer isso, o cara poderia criar um
> Agente via anotacao e atachar o evento e o metodo para fazer isso
> explicitamente...e, nesse caso, isso vai para o historico e ~e usado
> automaticamente nas proximas execucoes...
>
> Att,
>
Nesse caso de UF e Cidade, as heuristicas sao usadas em dois momentos:
1. Para definir a dependencia da Cidade para UF a partir da relacao
que existe onde Cidade "aponta" (tem um atributo) para o tipo UF. Ai
esta a dependencia.
2. Para definir o conteudo a ser exido dentro das comboxes de cidade e
UF, que serao, provavelmente "nome" para a cidade e "nome" para UF.
Porem, é provavel (mas nao certo) que o analista diga: olha, na combo
da UF por questoes de espaco na tela eu quero que seja mostrada a
sigla da UF, e nao seu nome completo. Nesse caso, nossa heuristica de
exibir nome na UF falhou. Para corrigir isso precisariamos algo como:
class UF extends Persistente { //Persistente é uma classe de
conveniencia (nao obrigatoria) que define alguns campos essenciais
para persistencia no sistema, como o Id.
@Default //ou outra anotacao, ainda nao esta decidido.
String sigla;
String nome;
}
Essa anotacao define que o campo padrao da UF nao é "nome", mas sim
"sigla". Assim, ao ser renderizada a combobox de UF na tela, o valor
que aparecera na combo sera a sigla e nao o nome da UF. Acho que isso
ficou claro, ok :-)
Bom, agora respondendo a sua pergunta sobre como isso fica armazenado
e é reusado pelo historico da ferramenta....
Quando definimos isso, a anotacao ficou compilada junto ao .class da
aplicacao. Provavelmente essa classe acabou indo para um arquivo Jar,
que foi deployado em um servidor, como o JBoss ou Tomcat mesmo. Nesse
ponto o sistema, chamamos ele de S1, esta em funcionamento....
Dai, algum tempo passou e vamos fazer o sistema S2. Casualmente,
precisamos no sistema S2 uma estrutura de Cidade e UF semelhantes as
do sistema S1. Entao, tres alternativas. A primeira é que sejam
reutilizados os arquivos .Java do sistema S1 para Cidade e UF. Nesse
caso, fizemos o tipico Control-C > Control-V. Isso é ruim, pois
estamos criando redundancia, e nao reuso. Simplesmente duplicamos
codigo-fonte e temos dois lugares para manutenir agora.... A segunda
alternativa é importamos para S2 o .Jar com as classes Cidade e UF
existentes no sistema S1. Melhorou um pouco, pois agora mantemos um
unico fonte e compartilhamos ele entre os dois sistemas. Ainda existem
problemas nisso, pois alteracoes no S1 devem ser bem projetadas, caso
contrario o impacto em S2 pode ser catastrofico (e vice-versa). Nos
casos 1 e 2 nao foi usado o historico do Merlin, pois efetivamente
reutilizamos as classes originais no novo sistema.
A alternativa 3 é a que mostra o uso do historico do merlin mesmo.
Supomos que criamos o sistema S2 com classes novas, criadas do zero
mesmo. Mesmo criando essas classes Cidade e UF do zero novamente, é
provavel que os atributos dessas classes tenham nomes iguais ou
parecidos aos que foram utilizados em S1. Isso pode ser provado de
varias formas, mas nao vem ao caso (...) O que importa é que esse
sistema S2 vai ser deployado em algum lugar. Digamos que esse lugar
seja o mesmo cliente do sistema S1. Isso implica que S2 e S1 vao
residir no mesmo servidor de aplicacao. E aqui esta a beleza, a
obscenidade e o ponto-chave do historico do merlin.
Ao S2 ser deployada, quando a tela do usuario no sistema S2 for
exibida para mostrar a Cidade e a UF, o Merlin vai buscar nao somente
as informacoes de Cidade e UF do sistema S2, mas sim uma media
ponderada daquilo que existe no classpath do sistema S2 e tambem do
sistema S1. Talvez S2 nao tenha definido uma anotacao @Default para o
campo sigla, mas em S1 isso foi usado. O merlin detecta isso e ao
renderizar a tela para a UF no sistema S2 a saida é uma combo que
mostra a sigla em seu conteudo.
Mas como é possivel acessar dados de S1 nesse caso? A resposta sao os
classloaders do servidor de aplicacao. Discussoes pesadas fora, todo
classloader de um servidor de aplicacao é uma arvore com um nodo root.
O merlin varre os classloaders do servidor de aplicacao e faz suas
buscas e taxas de acerto para inferir, nesse caso, o campo sigla. Essa
é a beleza do negocio.
A obscenidade tambem é consequencia disso. Em outras palavras, o
merlin descaradamente (e sendo um serviço ele pode fazer isso)
bisbillhotou por todas as aplicacoes instaladas no servidor de fez
suas inferencias...
E o ponto-chave reside ai: e se S2 nao estiver no mesmo servidor de
aplicacao que S1, ou mesmo nem estiver em um servidor de aplicacao?
Bom, dai nao existe um historico! Uma alternativa seria adicionar no
classpath de S2 as classes de modelo de S1, mas isso poderia ferir
algumas regras da empresa (seguranca, sigilo, etc.). A questao é que
somente existe historico se existir um contexto maior.
Finalizando (ufa) mesmo que S1 e S2 vivam felizes no mesmo servidor de
aplicacacao, teremos problemas. Vai que S1 sofreu uma manutencao e o
@Default foi tirado do campo sigla. Isso impactuaria em S2 que
voltaria a exibir o campo nome dentro da combo de UF (....) Sao esses
problemas de gerencia de historico que eu comentei na palestra. Para o
momento, tenho algumas ideias de como fazer esse controle, mas o foco
mesmo é terminar a versao basica do framework. E como o suporte ao
historico tem prioridade menor, esse é um problema a ser explorado
mais tarde.
Att,