terça-feira, agosto 22, 2006

Model-based generation

O dia de hoje não foi dos mais produtivos mas, enfim, fiz algo de útil que eu já deveria ter feito há algumas semanas: comecei a procurar artigos para a minha dissertação - os mesmos que eu já tinha e foram sei lá para aonde quando meu HD pifou...
Os tipos de artigos que procuro, em sua maioria, são relativos à geração baseada em modelos (model based generation), o que é justamente a tecnlogia que o Merlin utiliza para geração das telas de cadastro. O que difere muito (e isso eu posso garantir que é em 100% dos artigos e textos pesquisados até o momento) é que, enquanto o Merlin objetiva somente telas de cadastro (as interfaces CRUD), todas as abordagens estudadas buscam obstinadamente a geração de qualquer tipo de interface de usuário. Para isso os autores sugerem diversos modelos-base: modelos de tarefa (task models), modelos de interação (interaction models), modelos de domínio (domain models) e outros elementos, como camadas abstratas de controles, de eventos, de regras e um sem-número de outros recursos, todos visando alguma forma de abstração que permita minimizar o esfoço de programação e aumentar a eficácia das suas propostas.
Na prática, o que eu vejo como conclusão de toda essa panacéia é (i) a redundância de idéias, as quais vagueiam por caminhos diferentes buscando um objetivo comum; (ii) a total falta de aderência a padrões de mercado, uma vez que cada solução define (e advoga como a melhor) um padrão próprio e principalmente (iii) a quase total inutilidade da solução em ambientes reais de desenvolvimento. Sei, a expressão é forte mas, como desenvolvedor de sistemas - o que sou, não vejo aplicabilidade nenhuma delas nos meus cenários de trabalho: são soluções acadêmicas que projetam expectativas e não inserem suas propostas em cenários reais.
O Merlin, é uma ferramenta de geração de IU baseada em modelos, mas como princípio básico eu assumo que não quero gerar qualquer tipo de interface, mas sim - e somente - interfaces do tipo tela de cadastro. E isso simplifica muito as coisas. Com foco nesse tipo de IU, podemos abdicar de complexos modelos extras e balizar toda a geração em um modelo essencial, que está presente sempre: 0 modelo de objetos (de persistência) do sistema. Além disso, qualquer decoração no modelo (que visa aumentar a semântica) é feita com base em padrões de mercado, como o Java Annotations e em frameworks consagrados, como o Hibernate, o EJB e agora, talvez o JBoss Seam. Ainda, com vistas a manter a sintonia com o mercado, o projeto evolui com vistas as novas especificações que ainda estão bem no início, como o Java Bindings (JSR 295) e o Swing Application Framework (JSR 296) além, é claro, de compatibilidade total com tecnologias já em uso, como o Groovy, o BeanShell, AOP e conceitos bem-formados, como a programação baseada em eventos (Event Driven Programming, do Eiffel).
Mas isso tudo não é garantia de sucesso e é justamente por isso que a gente perde madrugadas lendo tutoriais, baixando artigos diversos e, muitas vezes (infelizmente), colocando eles no lixo, porque infelizmente as pessoas esquecem que frameworks devem ser usados no dia-a-dia e não somente terem seus conceitos publicados em sites, conferências e revistas especializadas.

domingo, agosto 13, 2006

Sobre a média do histórico

No último post, eu falei sobre o uso de estimativas para o histórico e que isso não era trivial. De fato, a computação de médias sobre valores do histórico é algo que deve ser pensado com calma. Por exemplo, vamos supor que o sistema S1 teve o campo "Usuario.nome" mapeado para "Nome do usuário" e no sistema S2 esse campo foi mapeado para "Nome" simplesmente. No sistema S3, qual será o valor que o sistema de histórico deve sugerir para esse campo? Com uma média simples, o valor poderia ser 50% para cada e, na prática o sistema de histórico, nesse caso, não ajudaria nada.
Pois bem. Eu imagino que o sistema de histórico deve usar uma escala temporal ascendente de pesos para o cálculo. Como assim? É simples, as coisas que são mais recentes devem ter um peso maior. No caso acima, o valor inferido pelo sistema de histórico deveria ser o valor de S2, ou seja, em S3 a sugestão para "Usuario.nome" seria "Nome".
Mas qual o argumento para isso? O argumento é simples: evolução. Em outras palavras, considero que a cada novo desenvolvimento a equipe incorpora conhecimento ao sistema, de forma que as novas decisões são as mais consistentes. Nesse sentido, as decisões tomadas para o sistema S2 são mais relevantes que as tomadas para o sistema S1. Claro, existem aspectos que fogem ao escopo do problema (o sistema S3 pode ter sido construído com mais pressa e menos cuidado; a nova equipe de desenvolviemento tem menos experiência no negócio; estagiários foram contratados; etc, etc e etc.). Mas isso não tem como saber, a não ser que seja parâmetro de configuração e, nesse caso entramos no problema do grafo infinito de escolhas...Deixa pra lá.
A questão que surge aqui é a seguinte: Quais os pesos que devem ser aferidos para cada ponto no histórico? Pode ser uma escala linear, como "S1=x, S2=2x, S3=3x", uma escala com valores exponenciais, como "S1=x^1, S2=x^2, S3=x^3" ou alguma outra. Na prática, acho que a linear seria mais interessante e menos agressiva. Outra alternativa seria deixar isso na configuração, de forma que o desenvolvedor tenha liberdade de optar por qual escala utilizar e que pesos associar a cada ponto do histórico. Mais um tópico a ser estudado.

quinta-feira, agosto 10, 2006

Aonde eu andava?

Tempo passou até que eu voltasse a escrever. E coisas ocorreram nesse meio tempo. E como ocorreram. Mas deixamo-as de lado e vamos falar de assuntos relacionados à...telas de cadastro, claro.
Estou pensando no Merlin para dizer a verdade. E para ser mais exato, no mecanismo de realimentação dele.
O Merlin, brevemente, é um gerador de telas de cadastro baseado em modelos. Em palavras de programador, como eu gosto, ele lê, em tempo de execução e via reflexão, o modelo de dados (as classes POJO) do sistema e, usando uma série de heurísticas e outras regras, ele renderiza (e esse é o termo que acho mais correto) as interfaces de usuário para edição de dados, ou, no jargão dos desenvolvedores, as telas de cadastro. Em suma é isso, mas na prática o negócio é bem complexo. Mas funciona. E como funciona.
Muitas abordagens semelhantes (embora todas essas gerem código - e o Merlin não) tentam fazer coisas parecidas. Mas elas são mais complicadas (e nada práticas). Mas e a realimentação? O Merlin baseia-se em um esquema de realimentação de contexto. Em palavras mais simples, o Merlin considera todo o histórico de desenvolvimento para gerar uma tela de cadastro. Por exemplo, se no sistema S1, você disse que o campo "br.com.minhaEmpresa.sistemaS1.modelo.beans.Usuario.descricao" deve ser renderizado na tela (de cadastro) como "Descrição do usuário", lá no sistema S2, S3...Sn, quando ocorrer algo parecido, o Merlin vai "se lembrar" disso e vai fazer isso automaticamente pra você. Veja a figura abaixo:
Na verdade, o Merlin "se lembra" de tudo. E mais. Ele usa um mecanismo federado para isso. Isso significa que, caso sua empresa (de desenvolvimento de software) tenha filiais espalhadas por cidades, estados ou mesmo em países diferentes, você pode configurar uma federação e o histórico de qualquer um desses lugares será compartilhado entre todos. Mas para isso funcionar, é necessário um compartilhamento de informações muito grande. Na prática, o classpath de todas as aplicações desenvolvidas (S1, S2, S3, Sn) em todas as filiais, deve ser compartilhado. E ai as coisas começam a ficar complicadas. Nesse ponto entram mecanismos de gerência de escrita, de versionamento, de modificação, de atualização do histórico, de propagação de modificações e, óbvio, de segurança. E isso são somente alguns problemas envolvidos.
O Merlin é tema da minha dissertação de mestrado e, a realimentação deve ser um dos capítulos do trabalho. E imagino que será o maior deles (e bem desproporcional, para dizer a verdade). Tenho planos na cabeça de como fazer isso, mas são somente planos. Preciso diagramar, testar e implementar muito antes de tomar uma decisão. Preciso estudar sobre o próprio conceito de federação, sistemas de métricas e estimativas (sim, pois um histórico não é somente uma média aritmética de pontos - a coisa é bem mais complicada. Vou falar disso em outro post), mecanismos de armazenamento e configuração, propagação e técnicas de mensageria, cache e persistência. E isso são somente alguns itens da "famosa" realimentação.
Deve ser por isso que nenhuma outra ferramenta que eu tenha pesquisado até agora implementou isso. Em suma, para dizer a verdade, somente um dos artigos comentou, veja bem somente comentou, que seria interessante o uso de informações históricas a fim de tornar as ferramentas mais pró-ativas. Bem, e tudo isso foi somente um ponto dentro do Merlin, que é um dos meus a fazeres no momento. Que esses próximos 4 meses sejam longos. Bem longos.