terça-feira, outubro 31, 2006

Sem comentários

Terminei o último post dizendo que eu ia falar sobre o que imagino como o futuro (da forma de desenvolvimento) dos sistemas e aplicações. Porém, uma coisa triste aconteceu depois que eu resolvi instalar o BSPlayer para ver o primeiro episódio de Taken, do Spielberg: Blue Screen no Windows!
Passei a madrugada e o dia inteiro tentando recuperar a instalação, mas não teve jeito. Depois de muito suar e uma pilha de backups em DVD, acabei reinstalando o Windows (na verdade, nesse momento, ele tá no meio da instalação ainda - agora to usando o outro note com Linux, o que detesto).
Assim, depois dessa história triste, não vou desperdiçar um assunto tão interessante como o futuro da programação em um post escrito com o coração machucado (...)
Mas pra não deixar você triste, vou recapitular a questão dos agentes e sua implicação no tocante à ligação tardia entre controles, eventos e regras de negócio.
Quando eu disse que existia uma consequência do uso dos agentes em relação ao baixo acoplamento e alta coesão, entende-se que, ao usar agentes para formar a tríade controle-evento-ação, isso se dá de forma que não existem dependências sintáticas no código-fonte do sistema. Em palavras de programador (o que eu gosto), não existem declarações import na classe de bean. Veja isso abaixo:

package a.b.c.d;

public class Cliente {

@Agent("focusLost", "validarDescricaoPessoalDoCliente")
String descricaoPessoal;

}

Nesse pequeno exemplo, a classe bean Cliente possui uma propriedade chamada descricaoPessoal, a qual é mapeada durante a execução do sistema para um controle do tipo caixa de texto (bom, pelo menos esse é o comportamento inicial previsto do Merlin, mas pode mudar...). A esse controle, está ligada à ação validarDescricaoPessoal, a qual é invocada quando ocorrer o evento focusLost do controle, ou seja, quando o foco de trabalho do usuário sair do controle de texto referente à propriedade em questão.
A pergunta que surge aqui é: O que é essa ação? Uma ação nada mais é do que uma regra de negócio e, como tal, está implementada em um método qualquer.
Os métodos que implementam as regras de negócio podem estar em qualquer lugar: dentro do próprio bean, em um EJB, em um WebService ou, pasmem, podem ainda nem existirem fisicamente!
No nosso exemplo simples, a regra de negócio, ops, ação, poderia ser implementada como:

package x.y.w.z;

public class RegrasDeValidacao {

public void "validarDescricaoPessoalDoCliente" {
JTextBox descricaoPessoal = (JTextBox) Merlin.getControl("cliente.descricaoPessoal");
if (descricaoPessoal.getText().indexOf("http://")) {
JOptionPane.showMessageDialog("Você não pode colocar endereços web nesse campo.");
descricaoPessoal.requestFocusInWindo();
}
}
}

Essa regra simplesmente evita que o usuário digite um endereço web dentro do campo de descrição do cliente, exibindo uma mensagem de aviso e colocando o foco no controle novamente.
Percebe-se aqui que a ligação entre o evento focusLost e a regra de negócio validarDescricaoPessoalDoCliente é feita com o uso dos nomes baseados em texto puro, ou seja, Strings. Ao olhar o código da classe Cliente, percebe-se que a mesma não importa o pacote x.y.w.z que contém a regra de negócio. Ela também não importa nenhum pacote java.awt nem javax.swing, que conteriam o evento de foco. De forma análogoa, a classe RegrasDeValidacao não importa o pacote a.b.c.d para ter acesso ao controle da tela a ser renderizado. Na prática, isso significa que, em tempo de compilação, nenhum dos elementos da tríade controle-evento-ação se conhece.
É desse comportamento "aberto" que surge a pergunta: E se o programaodor escrever "ffocusLost" ao invés de "focusLost", ou "validarDescricaoPessoalCliente" ao invés de "validarDescricaoPessoalDoCliente", ou qualquer outro erro simples de digitação? A consequência é que o agente não conseguirá efetuar a ligação entre os elementos da tríade. Como resultado, a regra não será executada.
Bem, isso é extremamente perigoso, pois não temos como validar as se as ligações entre os controles, eventos e regras de negócio estão consistentes. Isso não é um ponto contra, uma vez que, usando a abordagem tradicional do Swing, a coisa fica toda consistida em tempo de projeto, pois as regras estão contidas em classes que implementam interfaces pré-definidas?
A resposta, felizmente é não. Como vou mostrar no próximo post existem meios de fazer essa validação antes do sistema executar.

domingo, outubro 29, 2006

Cada dia parece que sei menos

Nos últimos três dias fiquei na Internet procurando coisas mais empolgantes do que meus estudos de mestrado. Pra variar um pouco, procurei assuntos relacionados ao Merlin :-)
A sensação do momento é o Ajax. Na verdade faz tempo isso, mas tudo bem. Pensando nisso e no Java 6 que tá por vir e que conterá o Rhino como implementação padrão para scripting (subentenda-se aqui Javascript ou ECMAscript), me dediquei a repensar o mecanismo de scripting que estava implementando no Merlin. Por padrão, portei as idéias sobre Event Driven Programming da Eiffel para o meu framework e, de quebra incorporei o suporte a duas coisas que eu acho importante: inicialização de propriedades e ligação de scripts, ora bolas!
A inicialização de propriedades é uma funcionalidade importante quando não queremos que os controles gerados assim o sejam com base nos valores default computados pela dupla Configuração-Histórico. Nesse sentido, o Agente associado ao controle, além de ligar eventos e ações (como é o padrão em Eiffel), também permite coisas como "quero esse controle com fundo verde, fonte verdana itálica 11pt, texto branco e borda de 2px laranja" tudo isso em uma linha de comando, como essa:

@Agent(
property = "
background=Color.green;
font=new Font(\"verdana\",Font.ITALIC,11);
foreground=Color.white;
border=BorderFactory.createLineBorder(Color.orange,2)"
)
String nome;

Já a associação de scripts aos elementos de interface é uma comodidade versátil, como comenta John O'Conner em Scripting for the Java Platform (embora o exemplo que ele deu não me convenceu muito).
Por padrão, a engine do Merlin usa o BeanShell como interpretador de scripts. O BeanShell é um interpretador simples e otimizado, muito bom para as tarefas de corriqueiras de interface de usuário, como cópia de valores, arraste e aplicação de efeitos simples e validações. Linguagens como o Groovy, Javascript e outras que a JSR223 deve guiar também devem ser suportadas transparentemente pelo esquema que bolei. Em outras palavras, os agentes apontam para um script, seja ele interno (uma string) ou um mapeamento para um recurso externo (um arquivo ou endereço de rede, sei lá). De qualquer forma, basta ter o interpretador instalado que darei um jeito de detectar o tipo de script e automaticamente executá-lo.
Na prática, eu ampliei o conceito de agentes do Eiffel ao mesmo tempo que mantive a simplicidade e o baixo acoplamento, o que é muito bom (mas tem consequências que vou falar em outro post).
Entretanto, o termo Agente ainda não me convenceu muito...fica parecendo aqueles caras chatos do Matrix. Vou ficar pensando e se eu achar outra palavra melhor, o Eclipse me ajuda com um Control+Shift+R...
Tem mais coisas que fiz nesses últimos dias também, como ativar os lembretes via celular no Google Gmail (e aprender que existe um tal padrão iCal também), reativar o meu Netvibes e ficar mais uma noite sem dormir (se meu médico ler isso ele me puxa a orelha, no mínimo).
Bem, mas o que eu queria falar mesmo é sobre o futuro (futuro que eu prevejo) da programação, do desenvolvimento de sistemas e a própria forma com que encaramos as aplicações e a forma de usar os computadores. Mas isso eu falo no próximo post.
Att.

quinta-feira, outubro 26, 2006

Merlin, SBES e 3Layer

Semana passada, fui para o SBES 2006 apresentar o Merlin na Sessão de Ferramentas. Fiquei uma semana em Florianópolis, mas infelizmente não deu pra ir na praia porque o tempo nublado não ajudou nada...
Sobre o evento, vou ser sincero: eu esperava mais.
Tinha uns 200 participantes no total e alguns standes "meia-boca" de empresas como Google e Microsoft. Pra quem já foi num evento como Software Livre (que ocorre em Porto Alegre), o SBES não é nem a metade. Mas tudo bem, o público é outro...o SBES é cheio de doutores, mestrandos e afins (Isso me lembra Kpax: doutor, doutor, doutor, doutor). Pra quem gosta...
Na sessão que o Merlin foi apresentado, o organizador disse que 66 ferramentas concorreram esse ano e 21 foram eleitas para serem apresentadas e publicadas nos anais do evento. As 3 melhores ganharam premios de 6, 5 e 3 mil reais. Infelizmente o Merlin não foi uma delas - ficamos em quinto. Mas tudo bem, eu penso diferente...
E penso diferente porque, embora eu seja mestrando, sou no âmago um programador. E como programador, não vejo nada de útil naquela panacéia de ferramentas de gerência de requisitos que foram apresentadas (na prática, a cada 3 ferramentas, 2 eram para esse fim...). Não que não sejam úteis, mas as propostas que eu vi eram fracas (eu, como arquiteto ou analista aqui na 3Layer nunca usaria uma ferramenta que, para cadastrar um requisito fosse necessário preencher mais ou menos 10 campos adicionais, como prioridade, tempo, estimativa, custo, analista 1, analista 2, desenvolvedor, sub-requisitos, etc, etc, etc, etc....enfim....quero uma ferramenta para otimizar e não para complicar). Pior que isso, de que adianta ferramentas isoladas que não se integram com outras soluções (CASEs, banco de dados, gerenciadores de emails, diretórios de serviços, recursos adicionais, mecanismos de autenticação e outros que tenho na casa?). XMI? Que piada. Os apresentadores mesmo (em off, é claro) comentaram que o XMI não dá conta do recado...
Bom, enfim. Falando do Merlin...minha apresentação não ficou muito boa (sou muito perfeccionista, eu sei), mas expor todo o Merlin em 15 minutos é outra piada. Só pra apresentar o conceito de realimentação e as técnicas envolvidas daria mais de uma hora....mas tudo bem, é uma forma de melhorar meu poder de abstração e comunicação.
E por falar na apresentação do Merlin, vou disponibilizá-la no site do projeto para download (me cobrem).
E hoje páro por aqui porque o sono tá pegando.