terça-feira, 11 de março de 2014

Uma arquitetura diluída: Lógica de negócios


Continuando nossa série de artigos sobre arquitetura de software corporativo diluída, vamos agora mostrar como implementar a camada de lógica de negócios do nosso Microblog. Se você não viu o início da série, por favor consulte o "Set list".




"Por que?"

Outro dia, estava ouvindo a conversa de dois colegas, que estavam discutindo um novo projeto. Pelo que eu entendi, seria a primeira reunião da Equipe, e os requisitos nem estavam mapeados ainda. Porém, o papo era: "... nós podemos criar um Web service JBOSS-WS, com XML, e depois podemos usar o Hibernate e blá blá blá...". Os caras nem sabiam os requisitos e já estavam falando em JBOSS, em Hibernate e em outras coisas do gênero. Por que? Por que esse "acoplamento de plataforma" mental? Por que esse viés? 

Porque as pessoas investem tanto tempo, esforço e dinheiro para entender a "selva" de frameworks que compõem o "ecossistema" corporativo Java, que acabam pensando apenas de uma única forma... Não existe sequer uma lista de critérios, para que sejam analisadas outras opções. As decisões são tomadas ANTES de serem formuladas... Lamentável.

Lógica de negócios

A camada de lógica de negócios, ou "middleware", é o coração de qualquer sistema moderno. Nela, são executados os processos que vão agregar valor ao pedido do Cliente e gerar resultado para a Empresa. 

Na implementação antiga do microblog, a camada de negócios era dividida em duas partes, ambas sendo executadas dentro de um Container Java EE (Tomcat, JBoss etc). A primeira parte, era representada por um "pedaço" da camada de apresentação, que era executada no Container, sendo composta pelo "ManagedBean", uma classe exigida pelo framework Javaserver Faces. A outra parte era o componente de negócios que o "ManagedBean" acessava, de modo a acionar os processos necessários para o MicroBlog funcionar. 

Várias coisas eram gerenciaras pelo Container Java EE, incluindo o "gerenciamento de sessão", ou a manutenção do Estado da conversação. Nessa nova arquitetura, a sessão é mantida em seu lugar devido: o Servidor de Banco de Dados, e a aplicação é totalmente "Stateless". 

Para mim, Javaserver Faces já deu... Não faz sentido algum usá-lo em uma aplicação moderna. Duvida disso? Então tente migrar o MicroBlog, que foi feito há uns dois anos, para a última versão do JSF (2.2). Veja se consegue fazer isso com baixo custo e risco... Com certeza, haverá momentos em que você vai considerar jogar tudo fora e fazer novamente...

Então, eu vou criar uma camada de lógica de negócios mais simples, retirando dela a "missão" de gerenciar Estado, e diminuindo o "acoplamento de plataforma" existente. Ela será assim: 
  • RESTful Webservice feito com Jersey (JAX-RS);
  • Rodando com um Container Jetty embutido, ou seja a aplicação se auto executa;
  • Usando JSON como mecanismo de troca de informações com as outras duas camadas (Apresentação e Persistência).
"Peraí...", você dirá, "... mas você continua usando Java EE!" Sim, eu continuo usando Java EE! Mas de forma diluída e transparente! A função do Container é apenas permitir à Classe do meu Webservice existir... O Container vai fazer uma e só uma coisa: Abrir e gerenciar conexões TCP/IP. Só isso.

Não tem "deploy", não tem configuração, não tem Hibernate, não tem JNDI... Ou seja, é como se fosse uma aplicação Java "standalone".
Vamos ao "Snippet Gist": 



Como pode ver, o Jersey é bem simples de usar, e eu estou recebendo os objetos JSON como Strings. Eu só tive que configurar as dependências no "pom.xml" (vou mostrar no último artigo) e criar um "web.xml":



A configuração da aplicação Web e do Container, é feita no método "main" da classe do Web Service:

    public static void main(String[] args) throws Exception {
        server = new Server(8080);
        WebAppContext context = new WebAppContext();
        context.setDescriptor("src/main/webapp/WEB-INF/web.xml");
        context.setResourceBase("src/main/webapp");
        context.setContextPath("/");
        context.setParentLoaderPriority(true);
        server.setHandler(context);
        server.start();
        server.join();
            
    }

Desta forma, basta executar a classe que o Container sobe e inicia a aplicação. E posso iniciar várias instâncias, passando a "porta" e até o "ip" via argumento de linha de comando, se eu quiser.

E, para testar tudo, posso usar o Apache HttpClient:



Conclusão

Eu não implementei todos os métodos que a página pode chamar, e vou fazendo aos poucos, mas já dá para você ter uma ideia de como ficará a aplicação final. Agora, só falta a camada de apresentação, que será composta exclusivamente por páginas HTML 5 com Javascript / jQuery.

Ao final, vou publicar um zip completo, com testes e tudo mais.

Espero que você esteja gostando dessa alternativa!