quinta-feira, 20 de março de 2014

Arquitetura diluída: "limando" o Java EE !


Cara, é hora de cortar a árvore de vez! Vamos "limar" o Java EE da nossa aplicação, e das nossas vidas! Vamos ver uma alternativa de arquitetura diluída mais radical ainda que a do artigo anterior. Vamos mostrar o que as novas tecnologias, criadas no século 21, podem fazer. Chega de "J.." isso... "J..." aquilo, vamos desenvolver de maneira ágil, usando uma arquitetura ágil.

Atenção: Pode causar revolta, leia e use com sabedoria!




Liberte-se da tirania do ecossistema Java!

Por anos a fio, temos sido verdadeiros escravos dessa tecnologia. Coisas como "Mapeamento O/R", "Servlets", "JSF", "EJB", "XML", "SOAP", vem nos assombrando diariamente, aumentando a complexidade dos nossos projetos, e, de quebra, o nosso custo. E nem sempre conseguimos repassar isso integralmente ao Cliente.

Eu tenho um amigo Consultor, que tem alguns sistemas feitos em Clipper! Sim, no velho e bom Clipper! E ainda tem novos desenvolvimentos! Certa vez, eu sugeri que ele migrasse seus sistemas para Java, afinal, era uma plataforma mais moderna. Ele me disse o seguinte:
"Para começar, eu teria que usar e justificar ao meu Cliente o uso de um Container. Em segundo lugar, o de um DBMS, e depois, tudo o que eu fizesse demoraria o triplo do tempo. Hoje, eu entrego uma solicitação de mudança em menos de 5 dias, você me garante que isso iria continuar, na nova Plataforma?"
É claro que eu tentei argumentar, que o Clipper era muito antigo, e não tinha mais suporte, e blá-blá-blá, porém, ele me cortou com o seguinte argumento: "Quem disse que eu uso Clipper? Meus sistemas rodam em Linux e eu uso XHarbour!"

E eu fiquei completamente sem argumentos...

Java não é ruim. É uma linguagem interessante, para aquilo a que se presta: "Compile once and run anyware", ou seja, uma linguagem poderosa e extremamente portátil. Para mim, o Java EE deveria ter parado na era dos Servlets, que eram realmente úteis. Talvez, o JSP também seja interessante, como alternativa ao PHP. Só que, depois disso, a Comunidade Java "endoidou" e passou a "viajar na maionese", criando um castelo de frameworks sobre frameworks sobre frameworks, cujo único objetivo parece ser o de perpetuar o uso dos próprios frameworks!


Java EE é um castelo de frameworks!

E você não precisa acreditar em mim! Tanto é verdade, que, a partir do Java EE 6.0, eles criaram o conceito de "Profiles", e passaram a adotar a modularização OSGI, de modo a tentar diminuir a "Complexidade Acidental", e tornar o Java EE mais flexível.

Mas, não adianta... O Java EE continua a ser um monstro, que embute "soluções que você não precisa, para problemas que você não tem"!

Na série de artigos que demonstram uma arquitetura diluída, usando o microblog, eu usei as seguintes tecnologias:

Eu ainda uso Java EE, mas o "castrei" de tal forma, que o Jetty só faz o papel de "Socket Server", mais nada. E eu ainda uso os benefícios do Jersey para criar um Webservice bem simples, quase um POJO. 

Bem, a vantagem desse tipo de arquitetura é que nós diluímos as responsabilidades por vários nós e plataformas diferentes. Por exemplo, chega de "encapsular" HTML e Javascript! Ao invés de Javaserver Faces, e de um Container rodando ManagedBeans, como na versão original do microblog, eu faço as páginas HTML consumirem diretamente a minha camada de lógica de negócios, através de uma interface REST.

E outro exemplo, ao invés de fazer um mapeamento O/R pesado, usando JPA, eu simplesmente uso um banco NoSQL. 

E diluí as responsabilidades o Java EE, movendo o gerenciamento de estado para o Banco de Dados. Simples e prático.

Cada um no seu quadrado!

Cada componente da arquitetura diluída, tem menos responsabilidades, e usa uma interface sem acoplamento de plataforma, ou seja, cada componente pode ser substituído por outro, feito em qualquer linguagem, sistema operacional ou framework. 

Na primeira versão, eu fui um pouco conservador, para mostrar a você que é possível "brincar de casinha" com o Java EE, bem comportado e "domado". Assim, preservamos nosso investimento em capacitação e em código legado. Porém, agora chegou o momento de radicalizar! E podemos fazer isso de várias formas e maneiras diferentes, eis alguns exemplos:
  • Substituir ambas as camadas (Apresentação e Lógica) por uma aplicação Rails;
  • Substituir a camada de persistência por um componente orquestrado no Mule ESB;
  • Substituir a camada de lógica e a de persistência por scripts Node.js.
Cada alternativa pode apresentar vantagens diferentes. Podemos, por exemplo, nos livrarmos do Java EE de vez, substituindo nosso RESTful Webservice por um script Node.js. Ganharíamos agilidade e desempenho com isso. Porém, e se tivermos um grande legado Java? Reescrever tudo pode ser antieconômico! Então, pensei em uma nova versão para a demonstração:
  • Camada de apresentação: Continuará sendo HTML 5 com jQuery, falando com a mesma interface REST, usando JSON;
  • Camada de lógica de negócios: RESTful Webservice Node.js, usando Restify e JSON. Falando com o mesmo DAO MongoDB Java, usando o node-java;
  • Camada de persistência: O mesmo DAO MongoDB Java, que usa objetos JSON.

Node.js

O Node.js é "acachapante"! Após ver o que ele faz, e como faz, você se sentira "achincalhado", pois parece até que estão debochando de você. Mas é verdade! Ele é um componente para execução de código Javascript, com API para criação de servidores, que é baseado no engine Javascript do Google Chrome, o V8. Os scripts apresentam um desempenho alucinante, sem comparação com nada que a plataforma Java EE possa oferecer. Em um "benchmark" (DZone) com o Java EE, o Node.js chegou a ser 20% mais rápido, o que o habilita a ser uma excelente solução para aplicações distribuídas. 

"Mas o Node.js tem seus problemas..."

É claro que tem! Nenhuma solução é perfeita, nem mesmo o Java EE! Então, não é uma razão para adotarmos uma arquitetura diluída? Não é melhor diluir o risco? Eis alguns "flames" sobre o Node.js:
A questão é que, se você usa uma arquitetura diluída, pode diluir o risco, combinando o melhor de cada solução e deixando o pior de lado. Com o ecossistema Java, é muito difícil fazer isso, afinal de contas, sua aplicação inteira está "mergulhada" no Container, como uma mosca, que caiu dentro do copo de Chope.

Bão, então vamostrá como ficou... Eis o Gist da minha nova Camada de Lógica de Negócios:

Note que estou usando três pacotes npm (o mecanismo de pacotes do Node.js): "restify", para servir requests REST, "fs", para acessar o file system, e "java", para instanciar classes Java e invocar seus métodos.

Eu não pretendo criar um "tutorial" de Node.js nesse artigo, mas apenas mostrar que a solução é possível. Logo, não vou entrar em detalhes sobre a implementação. Se houver interesse, posso criar um tutorial ou um "crash course".

Eu coloco os jars necessários no "classpath" e depois preparo os "callbacks" que o meu Webservice irá responder. Eles serão chamados de acordo com o método e com a URL, o que é definido no final do script:


// Home page:
server.get('/mb',home)

// Logon call: /mb/server/session//
server.get('/mb/server/session/:username/:password', logon);

// Userdata: POST /mb/server/userdata 
server.post('/mb/server/userdata',userdata);

// Messages: POST /mb/server/messages 
server.post('/mb/server/messages',messages);

// Start server
server.listen(8080, function() {
  console.log('%s listening at %s', server.name, server.url);
});

E assim, minha aplicação foi modificada, mantendo as outras duas camadas (Apresentação e Persistência) sem modificações. Veja o resultado:

É claro que nem todos os métodos foram implementados! Ele está fazendo logon, e pegando a lista de mensagens. Para isto, ele precisa guardar o "token" de sessão dentro de uma variável, na camada de apresentação, repassando cada vez que acessa um método de negócio. A camada de negócio é totalmente "stateless", dispensando mecanismos de "session migration" e de "stick". Na verdade, você pode usar a página até com "cookies" desligados.

Conclusão

A intenção desse artigo não é ser um "flame" da plataforma Java EE, nem do ecossistema Java. Sua intenção é apenas mostrar que podemos repensar a maneira de desenvolver aplicações corporativas, preservando o Java EE ou não. Eu sou um desenvolvedor Java EE, com livros publicados sobre o assunto, logo, você pode imaginar como eu me sinto com relação a isso, além do mais, sou Arquiteto Corporativo Java (SCEA). Mas, como profissional, além de professor, tenho que divulgar a verdade.

O Node.js pode não ser a única ou a melhor solução, mas apresentou performance razoável, e eu demorei cerca de 4 horas para ter tudo pronto e funcionando. Alguns problemas surgiram, e eu tive que dar umas "googadas", mas nada muito sério. Como sempre, a documentação dos produtos é muito ruim.

Agora, tente substituir o DAO por uma implementação em Node.js!

Eu criei um ZIP contendo essa nova solução, caso queira baixar e rodar, lembrando que é o mesmo banco de dados do exemplo anterior.