SyntaxHighlighter

quinta-feira, 6 de janeiro de 2011

Como desenvolver aplicativos Java usando a infraestrutura Netbeans - Módulos (Parte 1)

Está primeira série de artigos do blog Java Milk tem por objetivo explorar o desenvolvimento de aplicativos usando como base o framework Netbeans. Está série é fortemente baseada no livro  "Netbeans Platform 6.9 Developer's Guide" recém publicado sobre este assunto. Os posts apresentados aqui seguirão a estrutura do livro e serão publicados concomitantes a minha leitura e interpretação do conteúdo. Em hipótese alguma serão traduções diretas do livro. Recomendo a todos a aquisição do livro, não só pelo conteúdo detalhado (muito além do que conseguirei postar aqui) mas também como referência ao material. Uma boa jornada a todos nós!


Sobre o desenvolvimento de aplicações modulares

Antes de dar inicio ao desenvolvimento de aplicações fazendo uso da plataforma netbeans vale a pena darmos uma olhada sobre alguns conceitos fundamentais de modularização, a base de todo desenvolvimento desta plataforma.

Com a complexidade cada vez maior dos aplicativos, o uso de técnicas tradicionais de desenvolvimento de software tendem a gerar códigos grandiosos e de difícil manutenção. Dado a exigência e pressão do mercado por novos recursos, a atualização do código facilmente leva a uma condição caótica de desenvolvimento. Em alguns casos começar um novo projeto acaba sendo a única saída.

Uma metodologia que vem ganhando bastante espaço é o projeto de aplicativos baseado em módulos. Essa metodologia segue a aquela máxima do "dividir para conquistar". Um projeto modular bem definido garante um bom reuso de seus módulos e permite que equipes de tamanho expressivo possam trabalhar juntas buscando um mesmo objetivo. Para que tudo isso aconteça os módulos devem obedecer a certas caracteristicas.

Características de um módulo

  1. Formato do empacotamento:

    independente da quantidade de recursos, um módulo deve por definição ser entregue em um único pacote, seguindo a mesma idéia de um arquivo JAR. No netbeans os módulo são encapsulados em um formato semelhando, com extensão NBM (NetBeans Module), contendo um arquivo manifest especificando suas características.
  2. Identificação:

    Cada módulo deve possuir uma identificação exclusiva. Além do nome tradicional de cada módulo, o netbeans  oferece uma chave "OpenIDE-Module" (definida no arquivo manifest do módulo) que permite especificar uma identificação exclusiva pra cada módulo.
  3. Versionamento:

  4. Cada módulo deve ser capaz de expor sua versão. Um módulo que dependa de outro para funcionar específica a versão mínima requerida. Os módulos Netbeans possuem dois tipos de versão: versão de especificação e versão de implementação, ambas definidas no arquivo mainifest através das chaves "OpenIDE-Module-Specification-Version"e "OpenIDE-Module-Implementation-Version" respectivamente. A primeira (especificação) delas é a mais importante pois representa a versão utilizada/vista por todos módulos. Esta versão segue a notação Dewey (ex: 2.14.5). A segunda (implementação) trata-se de um controle de versão interna, mais voltado para a implementação do código em si.
  5. Exposição das interfaces:

  6. Cada módulo deve ser capaz de especificar sua interface pública, ou seja, aquilo que será disponibilizado para que outros módulos possam acessar. Classes declaradas como pública e não disponibilizadas como interface pública do módulo, não estarão disponíveis a outros módulos. No Netbeans, um módulo declara explicitamente quais módulos serão expostos. A chave "OpenIDE-Module-Public-Packages" do arquivo manifest define os pacotes públicos.
  7. Dependência:

  8. Cada módulo deve possuir um mecanismo através do qual ele diz quais módulos ele depende para execução de suas tarefas. No Netbeans, um módulo declara dependência de outro módulo através da chave "OpenIDE-Module-Dependencies". 
  9. Ciclo de vida:

  10. Cada módulo possui seu próprio ciclo de vida, gerenciado pelo "runtime" da aplicação. O Netbeans gerencia a carga e configuração dos módulos.

Criando uma aplicação simples

Para consolidar essa primeira etapa de conceitos, vamos criar uma aplicação simples contendo dois módulos. Vamos configurar um dos módulos para expor seu conteúdo e fazer uso deste no segundo módulo. O objetivo é demonstrar os conceitos anteriores aplicados no netbeans e dar o ponta pé inicial no que veremos adiante. Veremos passo a passo como criar um módulo, como disponibilizar sua interface pra que outros modúlos possam utiliza-lo, como versiona-lo e como fazer referência a uma interface de um módulo.

  • O primeiro passo é criar um container onde residirá os dois módulos que iremos criar. Uma outra alternativa seria criar os dois módulos e instala-los como plugins do próprio ambiente de desenvolvimento que utilizamos, porém, dado ao objetivo deste primeiro exemplo, vamos criar uma aplicação completa (container), contendo esses dois módulos. Pra criar o container vá em "Arquivo", "Novo Projeto", escolha as opções "Módulos do Netbeans" e "Aplicativo da Plataforma Netbeans".
  •  Escolha um nome para este projeto (veja exemplo abaixo):
  • Ao término destes primeiros passos, será criado uma estrutura para este projeto. Veja na aba "Projetos", repare que uma das pastas do projeto corresponde aos módulos que farão parte deste conteiner.
  • Agora que temos nosso container, vamos criar o primeiro módulo, fique atento a estes passos pois serão os mesmos pro segundo módulo. Na pasta "Módulos" do projeto criado, clique com o botão direito e escolha a opção "Criar novo ...". Em seguida, preencha os dados deste primeiro módulo.

  •  Na próxima tela, defina o nome do pacote onde iremos definir o código deste módulo. Se você leu atentamente os conceitos de módulos irá se lembrar da propriedade "Identificação do módulo", pois bem, a propriedade "Base do nome de código" será a identificação deste primeiro módulo (Obs: Surgiu aqui uma dúvida quanto ao uso deste primeiro pacote como sendo também o nome de identificação do módulo. Uma vez que um módulo pode conter vários pacotes, por que o primeiro deles é privilegiado? Vamos tentar descobrir isso nos próximos capitulos).

  • Até aqui, se você der uma olhada na aba de projetos vai perceber que além do container (PrimeiroAplicativo), que agora possui um módulo, foi criado também um módulo(HelloService).

  • Agora que temos nosso primeiro módulo podemos adicionarmos algum código dentro dele. A composição dos módulos será tipicamente de um projeto Java, contendo pacotes e classes. Neste ponto, vamos adicionar uma classe também com o nome "HelloService" (Obs: não fiz o teste, porém acredito que qualquer nome poderia ser utilizado. No final das contas veremos que o importante mesmo será o pacote disponibilizado pelo módulo e consequênte as classes públicas que pertencerem a este). No módulo "HelloService" clique com o botão direito no pacote deste módulo e escolha a opção "Nova" - "Classe Java". Crie uma classe com o nome "HelloService" (obs: como disse anteriormente, poderia ser outro nome).


  • Agora que temos uma classe em nosso primeiro módulo "HelloService", vamos adicionar um método simples para de fato testarmos a exposição deste módulo aos demais, em nosso exemplo, ao segundo módulo que criaremos.

public void hello(String name){
        System.out.println("Hello " + name + "!");
    }

  • Até aqui criamos um conteiner para abrigar nossos futuros módulos, criamos um módulo e adicionamos uma classe com método público. Para darmos inicio ao relacionamento entre módulos, exposição de interface, versionamento de um módulo e ciclo de vida, precisamos criar um segundo módulo. Os passos são identicos ao que fizemos até aqui, crie um novo módulo com nome "HelloClient", crie uma classe de mesmo nome e em seguida adicione o código abaixo:

public static void main(String[] args){
        new HelloService().hello("Netbeans");
    }

  • Ops! Se você fez tudo certo até aqui, vai reparar que seu código não irá compilar, visto que a classe "HelloService", do módulo "HelloService" não existe para este módulo. Alguém poderia pensar imediamente que está faltando especificar o pacote ao qual está classe pertence (sugiro que façam o teste), porém, a solução vai um pouco além. Em nosso caso, a classe "HelloService" não está exposta por seu módulo, ou seja nenhuma interface foi especificada neste módulo. Para resolvermos isso, basta clicarmos com o botão direito em cima do módulo "HelloService" e alterarmos suas "Propriedades". No item "Versionamento de API 's" marque o único pacote que aparece disponível (já que criamos apenas um pacote dentro do módulo). Feito isso, estaremos disponibilizando todas as classes públicas deste pacote para que possam ser utilizadas por outros módulos.

  • Definido a interface exposta pelo módulo "HelloService" precisamos agora especificar a dependência do módulo "HelloClient" por esta interface. Para isso, clique com o botão direito em cima do módulo "HelloClient", entre em "Propriedades", selecione a opção "Biblioteca" e clique em "Adicionar dependência". Digite o nome do módulo que deseja utilizar (possui dependência) e clique em Ok. Feito isso a janela de "Propriedades"-"Bibliotecas" será atualizada, mostrando que o módulo "HelloClient" possui dependência do módulo "HelloService".

  • Pra concluir o uso da interface exposta é necessário especificar o nome do pacote, exatamente como fazemos quando desejamos utilizar uma classe presente em outro pacote.


import com.javamilk.netbeans.helloservice.HelloService;

public class HelloClient {

    public static void main(String[] args){
        new HelloService().hello("Netbeans");
    }
}
  • Tudo pronto para executarmos a aplicação. Você irá perceber, se já não desconfiava, que um novo splash do netbeans é executado, terminando em uma janela semelhanto ao ambiente de desenvolvimento Netbeans Java porém sem contéudo (views, editor de código, terminal de saída, etc). Isso acontece pq estamos utilizando o framework netbeans como base para desenvolvermos nossos aplicativos java. Para o que foi feito até aqui, obviamente que não faz o menor sentido utilizarmos tamanho recurso. Mas a idéia é ir muito mais além, claro que utilizando outro projeto. Este é apenas para nos ambientarmos quanto ao desenvolvimento de módulos, setup de seus relacionamento e visualização dos conceitos vistos aqui.
  • Antes de concluir esse simples aplicativo, vale a pena entendermos onde é especificado a versão do módulo e onde é especificado a versão mínima de um módulo dependente. Para especifirmos a versão com que um módulo é exposto aos demais, basta clicamors com o botão direito em cima do módulo (por exemplo: HelloService), entrarmos em suas propriedades e clicarmos em "versionamento de API's". Repare nos dois tipos de versão: especificação e implementação. Lembre-se que a mais importante é a versão de especificação (pois será a versão utilizada pelos módulos que possuem dependência deste).

  • Da mesma forma, um módulo que possui dependência de outro módulo, deve especificar em algum lugar qual a versão mínima requerida. Para visualizarmos isso, basta clicarmos com o botão direito em cima do modúlo "HelloClient", entrarmos em "Propriedades", "Bibliotecas", selecionar o módulo que possui dependência e clicar em "editar". Na janela seguinte, no campo "versão de especificação", seguindo o formato Dewey você consegue especificar a versão mínima requerida. Faça o teste colocando uma versão superior ao especificado no módulo "HelloService" e tente compilar. Um erro de compilação deverá ocorrer, já que o módulo "HelloClient" está tentando utilizar um módulo mais novo do que o fornecido.

Conclusão

Neste primeiro post vimos alguns conceitos fundamentais para uma aplicação módular, filosofia que utilizaremos para desenvolver qualquer aplicativo fazendo uso da plataforma Netbeans. Criamos um pequeno projeto, bastante simples, afim de expor tais conceitos e ambientarmos com o desenvolvimento de aplicações/modulos no Netbeans. Neste momento, acredito e tenho esperanças de que muita coisa interessante virá nos próximos capitulos. Até o próximo post!

Referências:

[1] Netbeans Platform 6.9 Developer's Guide

Um comentário:

  1. muito bom fera... Valeu pelo post. a muito tempo estava procurando um conteúdo desse nível.

    ResponderExcluir