[Pesquisar este blog]

sexta-feira, 19 de janeiro de 2018

POO::Fundamentos-04-Atributos

POO-F-03-Criação de Objetos POO-F-05-Métodos
Uma classe é um novo tipo de dados que pode ser definido pelo programador para descrever uma entidade real ou abstrata. Podemos entendê-las como um modelo ou como uma especificação para objetos de um tipo determinado, ou seja, descrevem de maneira genérica os elementos pertencentes a um dado conjunto. 


Em um programa, as classes representam os conceitos fundamentais da aplicação em termos da realidade 'modelada' por tais classes [9]. Para a programação, criar classes envolve dois aspectos essenciais: a modelagem dos objetos a serem representados e a implementação deste modelo.

Modelar uma classe é determinar uma descrição adequada e geral para o conjunto de objetos que desejamos representar, ou seja, para todas as sua ocorrências. 

Uma bola qualquer, cuja forma seja esférica, pode ser descrita por seu tamanho, cor, peso, material etc. Um modelo de bola, destinado a uma loja de materiais esportivos, talvez necessite incorporar outras características ao modelo da bola, agora vista como um produto. Já um clube que deseja controlar o empréstimo de seu material recreativo pode exibir diferentes necessidades. Assim, o mesmo tipo de objeto pode ser descrito de maneiras diferentes, conforme a aplicação do modelo, revelando a maior dificuldade desta tarefa: estabelecer modelos apropriados para as aplicações pretendidas e não apenas para descrever os objetos modelados.

As características que descrevem os objetos de uma classe são chamadas de atributos. Alguns atributos descrevem a aparência (o "ser") de um objeto, como sua cor, dimensões, peso etc.); enquanto outras representam estados (o "estar"). Uma lâmpada comum opera numa voltagem particular, com uma potência máxima, estando acesa ou apagada. Por exemplo, a lâmpada é 110V e  é 40W e está apagada. 

Uma classe Lampada pode ser declarada em Java ou C# como:

class Lampada {
   double voltagem;
   double potencia;
}

Cada atributo (ou campo) é como uma variável que faz parte da classe, por isso a outra denominação técnica de variável-membro, cuja sintaxe é:

class <NomeClasse> {
   [acesso] <tipo> <nomeMembro> [ = <exprTipo>];
}

Onde:
  • NomeClasse é o nome da classe;
  • acesso é o especificador de acesso opcional;
  • tipo é o nome do tipo deste membro;
  • nomeMembro é o nome deste membro; e
  • exprTipo é uma expressão que resulta num valor do tipo que pode inicializar o membro.
Os especificadores de acesso serão vistos na lição sobre encapsulamento.

Os membros de uma classe, no caso os seus atributos, podem armazenar valores para cada objeto existente. Desta maneira, para usar os atributos, devemos ter objetos.

Um objeto da classe Lampada pode ser criado com:

Lampada lamp1 = new Lampada();

O operador '.', denominado seletor, permite selecionar um membro de um objeto para ser utilizado. Assim podemos atribuir valores a atributos de um objeto com:

lamp1.voltagem = 110;
lamp1.potencia = 40;

De maneira análoga ao uso de variáveis, atributos de objetos podem ser usados em expressões ou exibidos para o usuário:

// Java ou C#
double corrente = lamp1.potencia / lamp1.voltagem;

// Java
System.out.println("Voltagem = " + lamp1.voltagem);
// C#
Console.write("Potencia = " + lamp1.potencia);

Outro objeto da classe Lampada pode ser criado com:

Lampada lamp2 = new Lampada();

E com ele podemos fazer:

lamp2.potencia = 100;
lamp2.voltagem = 220;

Ao atribuir valores aos campos do objeto lamp2, tais dados ficam armazenados na área de memória reservada para o objeto lamp2, não interferindo nos dados retidos pelo objeto lamp1. Pois cada objeto tem sua própria memória, permitindo guardar dados distintos dos demais objetos do seu tipo ou de outros.

Devemos observar que muitos objetos não podem ser descritos adequadamente apenas por seus atributos, requerendo também que suas ações, ou seja, suas capacidades sejam representadas. Uma classe incorpora o conceito de tipo abstrato de dados, definindo tanto conjunto de valores que representam este tipo como também o conjunto de operações sobre tais valores [10]. 

Por exemplo, um modelo de automóvel, para um simulador ou para um jogo, deve ser capaz de acelerar, frear e virar, ou seja, o modelo deve ser capaz de representar as ações dos objetos sob a forma de operações. Temos, portanto, que a modelagem de uma classe de objetos envolve a definição de atributos (que conterão os dados que descreverão sua aparência e estado -- esta lição) e de operações (que podem ser realizadas com tais atributos ou outros dados fornecidos -- a próxima lição), como ilustrado a seguir.


Cada classe define os atributos que seus objeto possuirão, de maneira que cada um destes possam ter valores distintos para cada um destes atributos, mesmo que tais valores sejam iguais (tal como dois objetos idênticos). A classe também define um conjunto único de operações para todos os objetos, ou seja, as ações realizadas serão as mesmas quanto à natureza, variando apenas em relação ao valor dos atributos de cada objeto. Esse é o assunto da próxima lição!

POO-F-03-Criação de Objetos POO-F-05-Métodos

Referências Bibliográficas

[1] JAMSA, K.; KLANDER, L.. Programando em C/C++: a bíblia. São Paulo: Makron Books, 1999.
[2] PAGE_JONES, M.. Fundamentos do Desenho Orientado a Objeto com UML. São Paulo: Makron Books, 2001.
[3] SOMMERVILLE, I.. Software Engineering. 6th. Ed. Harlow: Pearson, 2001.
[4] DEITEL, H.M.; DEITEL, P.J.. Java: como programar. 6a. Ed. São Paulo: Pearson Prentice-Hall, 2005.
[5] SAVITCH, W.. C++ Absoluto. São Paulo: Pearson Addison-Wesley, 2004.
[6] JANDL JR., P. Introdução ao C++. São Paulo: Futura, 2003.
[7] JANDL JR., P.. Java - guia do programador. 3a. ed. São Paulo: Novatec, 2015.
[8] RUMBAUGH, J.; BLAHA, M.; PREMERLANI, W.; EDDY, F.; LORENSEN, W.. Object-oriented modeling and design. Englewoods Cliffs: Prentice-Hall, 1991.
[9] STROUSTRUP, B.. The C++ Programming Language. 3rd Ed. Reading: Addison-Wesley, 1997.
[10] LANGSAM, Y.; AUGENSTEIN, M. J.; TENENBAUM, A. M.. Data structures using C and C++. 2nd Ed. Upper Saddle River: Prentice-Hall, 1996.

terça-feira, 16 de janeiro de 2018

POO::Fundamentos-03-Criação de Objetos

POO-F-02-Objetos, Tipos e Classes POO-F-04-Atributos
No mundo real, a existência de qualquer tipo de objeto exige que ele seja previamente criado ou fabricado, possibilitando que possa ser usado. A POO, como um modelo de programação que procura representar a realidade, também exige que os objetos sejam previamente criados para que possam ser utilizados.


Quando um livro é publicado, geralmente são impressos muitos exemplares, ou seja, objetos do mesmo tipo e também iguais em termos de suas características e conteúdo, mas fisicamente distintos. Cada exemplar de um livro específico é um objeto que tem "vida" própria, ou seja, passa a existir assim que sua produção é finalizada; pode ser armazenado, transportado, exibido e comercializado separadamente dos demais exemplares; pode ser usado e consultado; até mesmo descartado e destruído, quando este "ciclo de vida" se encerra, sem que o se passa com um exemplar, ocorra com outro.

Cada livro é um objeto que tem existência independente dos demais objetos, incluindo aqueles iguais (do mesmo tipo, com as mesmas características). Cada livro que existe é uma instância, um objeto distinto de um tipo específico.

Neste sentido, as classes são como modelos para a criação de objetos, pois definem as características (ou atributos) associadas a tais objetos, assim como seus comportamentos (ou operações). Assim, os objetos são sempre criados a partir de uma classe específica que serve como ponto de partida.

A criação de um objeto é, portanto, uma operação importante e especial, tanto que possui um operador próprio na maioria das linguagens de programação OO. No Java e no C# existe o operador new, responsável pela criação de novos objetos, uma operação denominada instanciação.

Além do operador new, é necessária a indicação da classe que originará o novo objeto, como na sintaxe abaixo:

<Classe> objeto = new <construtor>([lista_argumentos]);

Aqui:
  • Classe indica o nome da classe que determina o tipo do objeto;
  • objeto é a variável que "contém" o objeto;
  • new é o operador especial de instanciação;
  • construtor é uma operação especial de cada classe que determina como novos objetos serão criados; e
  • lista_argumentos opcionalmente fornece dados para a criação do novo objeto.
A classe Livro simples que segue, embora vazia, é sintaticamente válida:

class Livro {
}

Como a classe Livro existe, é possível criar novos objetos deste tipo com:

Livro livro1 = new Livro();
Livro livro2 = new Livro();

As variáveis podem ter qualquer nome válido, embora livro1 e livro2 são algo adequadas, pois ao mesmo tempo que dão uma pista sobre o tipo do objeto que contém, permitem diferenciá-los.

Os construtores, em Java e C#, como na maioria das linguagens OO, têm o mesmo nome que as respectivas classes, no caso a classe Livro. Também é comum que, quando nenhum construtor é fornecido pelo programador (nosso caso), o compilador adicione automaticamente um construtor para permitir a criação de objetos, o que se denomina construtor default, que não recebe argumentos. Assim, qualquer classe válida criada permite criar objetos.

Os construtores providenciam a alocação de espaço na memória para armazenamento do objeto, assim como sua inicialização adequada, conforme determinado pelo programador.

Após sua criação, os objetos podem ser utilizados, até que sejam destruídos, ou seja, removidos da memória. A destruição dos objetos ocorre em três situações: (i) por determinação do programador; (ii) porque o objeto sai fora do escopo onde foi criado; (iii) por conta do encerramento do programa.

Assim, as etapas de criação, de utilização e, por fim, de destruição, compõem o ciclo de vida dos objetos pode ser ilustrado como na figura que segue.


Outro aspecto importante é que nos sistemas de programação orientada a objeto, cada instância tem um identificador que permite diferenciar um objeto de outro, mesmo quando são iguais. Como um número de série de um produto qualquer, o número do chassi de um veículo ou o número MAC de uma placa de rede: identificadores únicos no universo das instâncias de um tipo de objeto específico. Aqui temos uma terceira característica importante da POO que é a identidade: cada objeto é único e deve ser univocamente identificado em sistema de programação orientada a objetos.

Com a criação de objetos, acabamos por discutir algumas questões fundamentais da OO:

  • Todo objeto é de um tipo específico/classe específica.
  • Os objetos da mesma classe, ou seja, do mesmo tipo, possuem as mesmas características (atributos) e comportamento (operações).
  • Todo objeto é criado é distinto dos demais, independente de seus tipos.
  • Todo objeto tem um ciclo de vida.
  • Todo objeto é único e pode ser distinguido dos demais.
Precisamos agora dotar nossas classes de características e comportamentos que permitam representar elementos da realidade e, com isso, tornar a técnica da OO útil na resolução de problemas. Atributos e operações são nossas próximas lições.

POO-F-02-Objetos, Tipos e Classes POO-F-04-Atributos


Referências Bibliográficas

[1] JAMSA, K.; KLANDER, L.. Programando em C/C++: a bíblia. São Paulo: Makron Books, 1999.
[2] PAGE_JONES, M.. Fundamentos do Desenho Orientado a Objeto com UML. São Paulo: Makron Books, 2001.
[3] SOMMERVILLE, I.. Software Engineering. 6th. Ed. Harlow: Pearson, 2001.
[4] DEITEL, H.M.; DEITEL, P.J.. Java: como programar. 6a. Ed. São Paulo: Pearson Prentice-Hall, 2005.
[5] SAVITCH, W.. C++ Absoluto. São Paulo: Pearson Addison-Wesley, 2004.
[6] JANDL JR., P. Introdução ao C++. São Paulo: Futura, 2003.
[7] JANDL JR., P.. Java - guia do programador. 3a. ed. São Paulo: Novatec, 2015.
[8] RUMBAUGH, J.; BLAHA, M.; PREMERLANI, W.; EDDY, F.; LORENSEN, W.. Object-oriented modeling and design. Englewoods Cliffs: Prentice-Hall, 1991.

quinta-feira, 11 de janeiro de 2018

POO::Fundamentos-02-Objetos, Tipos e Classes

POO-F-01-Características POO-F-03-Criação de Objetos

Compreendemos e interagimos com o mundo, em grande parte, através do conceito de objetos [6], que, conforme Jamsa & Klander [1], são simplesmente coisas ou entidades do mundo real.


Observando os objetos que existem ao seu redor, note que, provavelmente, todos são conhecidos. Mas as palavras que dão nome a cada um destes objetos são, de fato, nomes? A maioria dos termos que dão nome aos objetos conhecidos são substantivos e, diferentes dos nomes próprios, dados às pessoas, animais de estimação ou coisas especiais, os nomes dos objetos acabam designando algo maior: categorias de objetos. Habitualmente criamos categorias de objetos, usando o nome destas categorias para lidar com os muitos objetos que pertencem a cada categoria.

Tomemos um objeto conhecido, por exemplo, um livro. A simples menção do nome desta categoria de objeto nos leva, automaticamente, a imaginar algum livro e associar características destes objetos, como tamanho, espessura, título, conteúdo, autor e eventualmente outras que para nós estão ligadas a tal objeto. Também sabemos que existem muitos livros, que combinam, diferentemente as características possíveis destes objetos. Então, ao entrar numa livraria ou biblioteca, você não tem dificuldade de reconhecer os muitos livros distintos que lá existem, a despeito dos variados formatos, tamanhos, espessuras, capas e conteúdos variados [6][7].

Isto indica que somos capazes de reconhecer este tipo de objeto pelo conjunto de características comuns com as quais os descrevemos. A palavra livro serve, assim, para designar um imenso conjunto de objetos que compartilham um grupo de características comuns, ou seja, uma categoria de objetos, o mesmo que um tipo de objeto ou uma classe de objetos. Na POO, os termos classe e tipo são frequentemente considerados como sinônimos. 

Surgem aqui dois conceitos importantes da orientação a objetos:
  • classificação, que consiste na criação de categorias ou tipos de objetos que compartilham características e comportamento comuns;
  • encapsulamento, que estabelece um agrupamento de ideias correlacionadas e pode ser tratado como uma unidade por meio do seu nome.

No exemplo que analisamos, livro é uma classe de objetos que encapsula conceitos como formato, tamanho, espessura (ou número de páginas), título, autor e eventualmente outros.´

Os conceitos encapsulados em uma classe podem, então, representar características de seus objetos (como o tamanho de um livro), ou mesmo estados de seus objetos (como a situação ligado/desligado de uma máquina). Estas características e estados são conhecidas como atributos.

Além dos atributos, uma classe pode possui operações, ou seja, pode incluir comportamentos ou ações possíveis para os objetos da classe. Em geral, as operações atuam sobre os atributos e, assim, podem modificar as características ou estados dos objetos da classe.

Temos assim que os objetos encapsulam atributos (características e estados próprios) e também operações (comportamentos e ações possíveis), como ilustrado a seguir.


A sintaxe para declaração de uma classe utilizando a linguagem de programação Java é como segue:

<acesso> class <Nome> {
[declaração de atributos]
[declaração de métodos]
[declaração de construtores]
}

Entre os símbolos <> temos os elementos obrigatórios:
* acesso - especificador de acesso (que serão vistos na lição Encapsulamento);
* Nome - nome da classe, dado por meio de identificador válido.

Entre os símbolos [] temos os elementos opcionais:
* declaração de atributos - que definem o tipo e o nome dos atributos da classe;
* declaração de métodos - que definem as operações presentes na classe;
* declaração de construtores - que definem as operações especiais de criação de objetos.

Uma classe simples, em Java ou C#, pode ser declarada como:

class Livro {
}

As classes podem possuir, opcionalmente, um número variável de atributos, de métodos e de construtores. Os atributos e operações de uma classe serão discutidos nas próximas lições.

Finalizando, para que os objetos do mundo real possam existir, devem ser criados ou fabricados, possibilitando que sejam usados. Na POO a criação de objetos é também uma etapa importante, que seja tratada na próxima lição.

POO-F-01-Características POO-F-03-Criação de Objetos

Referências Bibliográficas

[1] JAMSA, K.; KLANDER, L.. Programando em C/C++: a bíblia. São Paulo: Makron Books, 1999.
[2] PAGE_JONES, M.. Fundamentos do Desenho Orientado a Objeto com UML. São Paulo: Makron Books, 2001.
[3] SOMMERVILLE, I.. Software Engineering. 6th. Ed. Harlow: Pearson, 2001.
[4] DEITEL, H.M.; DEITEL, P.J.. Java: como programar. 6a, Ed. Pearson Prentice-Hall: São Paulo, 2005.
[5] SAVITCH, W.. C++ Absoluto. Pearson Addison-Wesley: São Paulo 2004.
[6] JANDL JR., P.. Introdução ao C++. São Paulo: Futura, 2003.
[7] JANDL JR., P.. Java - guia do programador. São Paulo: Futura, 2003.
[8] RUMBAUGH, J.; BLAHA, M.; PREMERLANI, W.; EDDY, F.; LORENSEN, W.. Object-oriented modeling and design. Englewoods Cliffs: Prentice-Hall, 1991.

POO::Fundamentos-01-Características da POO

POO-F-00-Apresentação POO-F-02-Objetos, Tipos e Classes
A programação orientada a objetos, ou apenas POO, é a técnica dominante no desenvolvimento de software. Todo programador e todo projetista de software deve  dominar os conceitos da orientação a objetos (OO) e das técnicas fundamentais de sua programação.


Concebida há várias décadas, a OO deu origem a muitas linguagens de programação de sucesso, como Eiffel, Smalltalk, C++, Java e C#, entre dezenas de outras. As motivações para utilização desta técnica de projeto e de programação são sua capacidade de representação, que facilita o projeto, além de sua constituição modular, que podem aumentar a produtividade e reduzir os custos de desenvolvimento e de manutenção.

É possível afirmar que, no sentido mais simples, um objeto é uma coisa ou entidade do mundo real [1]. Já o termo orientado significa dirigido ou direcionado.

Assim, o termo orientado a objetos, conforme Page-Jones, é intrinsecamente destituído de qualquer sentido [2], pois como o termo objeto se aplica a, praticamente, qualquer coisa, resulta em algo como "direcionado a qualquer coisa". Por conta disso, sempre houve considerável dificuldade a respeito de uma definição concordante desta denominação.

Comumente, o projeto orientado à objetos é compreendido como uma estratégia onde os projetistas de sistemas pensam em termos de coisas ao invés de operações ou funções [3]. A construção de um sistema orientado a objetos (OO) é a combinação de vários objetos que interagem entre si.

Outros autores, como Deitel & Deitel [4], Savitch [5] e o Page-Jones [2] preferem definir a orientação a objetos como uma técnica de projeto que agrupa um conjunto de conceitos fundamentais: classificação, encapsulamento, especialização, generalização, identidade, ocultação de informações, polimorfismo, retenção de estado e troca de mensagens.

Estes conceitos podem ser rapidamente definidos como segue.

Classificação

Consiste na criação de categorias ou tipos de objetos que compartilham características e comportamento comuns. É uma ação natural no nosso modo de compreender o mundo a nossa volta [6]. A classificação ocorre por meio da criação de classes (tipos de objetos), que são modelos que permitem a geração de novos objetos, que terão as mesmas características e comportamentos do modelo que os originou [2]. Uma classe pode abrigar características (ou atributos) do tipo, assim como comportamentos (ou operações) sobre suas características.

Encapsulamento

É o agrupamento de ideias correlacionadas na forma unidades, módulos ou classes, de maneira que tal conceito pode usado apenas por meio de seu nome [2]. O encapsulamento também determina a representação do objeto, ou seja, possibilita que um objeto seja usado apenas por sua aparência exterior [6]. 

Especialização

Mecanismo da orientação a objetos pelo qual é possível a criação de novas classes (tipos) a partir de outras existentes, para adição de características e operações. A especialização é usualmente denominada de herança, onde uma classe B compartilha características e operações definidas em outra A [6], ou seja, a herança (de B a partir de A) é habilidade de B no uso de elementos A, como se estivessem definidos no próprio B [2]. A herança permite a criação de famílias de classes.

Generalização

Capacidade de utilizar objetos de tipos diferentes considerando apenas seus elementos comuns, ou seja, aqueles usualmente herdados de seus ancestrais comuns. Isto permite que objetos efetivamente diferentes possam ser usados para a realização de uma tarefa específica, o que confere grande flexibilidade aos sistemas assim construídos. Também pode se referir a construção de classes genéricas, ou seja, capazes de realizar suas operações sobre conteúdos internos diferentes [2][7].

Identidade

É a propriedade de cada objeto de ser unicamente distinguido dos demais [6], ou seja, sua identidade, permitindo seu tratamento individual [2]. É comum a existência de um identificar de objetos (object identifier - oid) nos sistemas de programação orientada a objetos.

Ocultação de informações

Permitindo preservar informações importantes dentro do objeto, externando apenas o que se julga conveniente ou necessário. Partes da própria construção do objeto (sua implementação) podem ser ocultadas pelo mesmo mecanismo. A ocultação das informações é obtida por meio dos mecanismos de encapsulamento [2][6][7].

Polimorfismo

Mecanismo essencial dos sistemas orientados a objeto que possibilita admitir muitas formas. Na orientação a objetos o polimorfismo pode se manifestar no acionamento de operações, na generalização e especialização.

Retenção de estado

Se refere a habilidade de um objeto de guardar informações sobre seu próprio estado [2], ou seja, é a memória própria de cada objeto que serve para armazenar suas características individuais e também outros dados que mantém consigo (seus estados), usualmente na forma de atributos [6].

Troca de mensagens

Uma mensagem é o veículo pelo qual um objeto remetente (caller) transmite um pedido a um objeto destinatário (receiver) para que ele realize uma de suas operações [2]. Os objetos de uma mesma classe, ou seja, do mesmo tipo, são capazes de receber os mesmos tipos de mensagens [4], pois podem realizar as mesmas operações.

Os objetos mantêm informações próprias que constituem seu estado local, além de prover operações para modificar, de maneira limitada, tal estado.

Assim, um objeto combina dados e operações específicas, o que define um conjunto particular de responsabilidades. Um sistema OO é um conjunto de objetos que se inter-relacionam para produzir os resultados desejados [7]

Assim, a programação orientada a objetos é uma forma particular de organizar o desenvolvimento de software como uma coleção de objetos que incorporam tanto uma estrutura de dados como comportamentos [8].

POO-F-00-Apresentação POO-F-02-Objetos, Tipos e Classes

Referências Bibliográficas

[1] JAMSA, K.; KLANDER, L.. Programando em C/C++: a bíblia. São Paulo: Makron Books, 1999.
[2] PAGE_JONES, M.. Fundamentos do Desenho Orientado a Objeto com UML. São Paulo: Makron Books, 2001.
[3] SOMMERVILLE, I.. Software Engineering. 6th. Ed. Harlow: Pearson, 2001.
[4] DEITEL, H.M.; DEITEL, P.J.. Java: como programar. 6a, Ed. São Paulo: Pearson Prentice-Hall, 2005.
[5] SAVITCH, W.. C++ Absoluto. São Paulo: Pearson Addison-Wesley, 2004.
[6] JANDL JR., P.. Introdução ao C++. São Paulo: Futura, 2003.
[7] JANDL JR. P.. Java - guia do programador. 3a. Ed. São Paulo: Novatec, 2015.
[8] RUMBAUGH, J.; BLAHA, M.; PREMERLANI, W.; EDDY, F.; LORENSEN, W.. Object-oriented modeling and design. Englewoods Cliffs: Prentice-Hall, 1991.

Programação Orientada a Objetos

A programação orientada a objetos, ou apenas POO, é a técnica dominante no desenvolvimento de software. Como todo programador projeta software, consciente ou inconscientemente, é importante que tenha domínio pleno dos conceitos da orientação a objetos (OO) e das técnicas fundamentais de sua programação.

Para tratar todos os conceitos necessário, provendo alguns exemplos, o material foi dividido em partes, cada qual com seu conjunto próprio de lições, publicadas em posts separados.
  • Parte I -- POO Fundamental
  • Parte II -- POO Plena
    • Objetos que usam objetos
    • Objetos que compõem objetos
    • Objetos que fazem parte de objetos
    • Membros Estáticos
    • Herança
    • Polimorfismo
  • Parte III -- POO Avançada
    • Classes abstratas
    • Interfaces
    • Hierarquia de classes
    • Classes genéricas
    • Padrões de projeto
Neste momento, planejo produzir apenas a Parte I -- POO Fundamental. Se o material publicado tiver boa recepção, continuo com a série.

Finalmente, os exemplos utilizarão a linguagem de programação Java e também C#, para contemplar um conjunto maior de interesses.

segunda-feira, 8 de janeiro de 2018

Java 9::Jigsaw - a nova modularidade da plataforma (Parte III)

O Jigsaw trouxe um novo e interessante sistema de modularização para a versão 9 do Java, o qual soluciona muitos problemas das versões anteriores, além de proporcionar novas facilidades na construção de aplicações.
A parte III deste post traz um exemplo simples que mostra o essencial da construção de aplicações modularizadas, incluindo o uso do jlink. para a criação de imagens executáveis (runtime images), isto é, máquinas virtuais Java customizadas. A parte I abordou o conceito de modularidade e a especificação do novo artefato module trazida pelo Jigsaw; enquanto a parte II discute a implementação do Jigsaw na plataforma Java.
Ao longo deste post, use ';' como separador de diretório no Microsoft Windows e ':' no Unix/Linux. Note que %JAVA_HOME%/jmods é o diretório, no Windows que contém o módulo java.base.jmod (e os demais módulos padrão do JDK). Verifique sua instalação em caso de dúvidas.

Aplicação Simples (módulo único)

Uma aplicação simples é constituída por classes distribuídas em um pacote (ou mais) encapsulados em um único módulo. Além disso, estas classes não serão utilizadas por outras aplicações, ou seja, não serão exportadas para outros módulo, ou, em outros termos, observáveis por outros módulos.

Criaremos uma aplicação no estilo clássico do "Hello World" para começar.

1.
Crie um diretório Jigsaw em um lugar conveniente de seu sistema de arquivos. Entre neste diretório.
md Jigsaw
cd Jigsaw

2.
Crie um subdiretório para o código fonte (src), com subdiretórios para cada pacote e subpacote necessários, usando o seguinte esquema: src\<nome.pacote>\<subdir1>[\<subdir2>...].
Neste exemplo será necessário apenas um pacote (cujo nome longo é apenas ilustrativo).
md src\br.gov.sp.fatec.saudacoes\br\gov\sp\fatec\saudacoes

3.
Neste subdiretório crie o arquivo Main.java com o conteúdo que segue. Este é o código da aplicação simples que estamos construindo.
package br.gov.sp.fatec.saudacoes;

public class Main {
   public static void main(String[] args) {
      System.out.println("Olá Jigsaw!");
   }
}

4.
Navegue para o subdiretório que denomina o pacote (src\br.gov.sp.fatec.saudacoes):
cd ..\..\..\..\..

5.
Neste subdiretório crie o arquivo module-info.java, que é o descritor do módulo br.gov.sp.fatec.saudacoes, com o conteúdo que segue.
module br.gov.sp.fatec.saudacoes {
}

6.
Navegue para o diretório inicial (Jigsaw):
cd ..\..

7.
Crie um subdiretório para os módulos compilados (modules).
md modules\br.gov.sp.fatec.saudacoes


8.
Compile os arquivos de cada subpacote (apenas um neste exemplo).
(O comando abaixo foi separado em várias linhas para melhorar a legibilidade, mas deve ser fornecido em uma única linha!)
javac -d modules\br.gov.sp.fatec.saudacoes
      src\br.gov.sp.fatec.saudacoes\br\gov\sp\fatec\saudacoes\Main.java

A opção -d é seguida do diretório onde o código binário das classes deve ser armazenado, respeitando a estrutura de pacotes. O último argumento é o nome do arquivo que será compilado.

9.
Compile o arquivo de informação de cada módulo (apenas um neste exemplo).
(O comando abaixo foi separado em várias linhas para melhorar a legibilidade, mas deve ser fornecido em uma única linha!)
javac -d modules\br.gov.sp.fatec.saudacoes
      src\br.gov.sp.fatec.saudacoes\module-info.java

10.
É possível usar a JVM para listar os módulos disponíveis.
java --module-path modules --list-modules
A opção --module-path é seguida de uma lista de diretórios que contém os módulos não integrantes do JDK/JRE. A opção --list-modules determina a ação a ser tomada pela JVM.

11.
E também usar a JVM para obter informação de módulos observáveis.
(O comando abaixo deve ser fornecido em uma única linha!)
java --module-path modules
     --describe-module br.gov.sp.fatec.saudacoes

Aqui a opção --module-path é seguida de uma lista de diretórios que contém os módulos não integrantes do JDK/JRE. Já a opção --describe-module deve ser seguida do nome do módulo que deve ser descrito.
O resultado deve ser como segue:
br.gov.sp.fatec.saudacoes file:///C:/Users/Jandl/workspace/Jigsaw/modules/br.gov.sp.fatec.saudacoes/
requires java.base mandated
contains br.gov.sp.fatec.saudacoes

Observe que o módulo br.gov.sp.fatec.saudacoes requer (obrigatoriamente) o módulo java.base, apesar de seu descritor não explicitar tal necessidade.

12.
Para executar a aplicação simples, organizada como um módulo, usamos o comando que segue.
(O comando abaixo deve ser fornecido em uma única linha!)
java --module-path modules
     -m br.gov.sp.fatec.saudacoes/br.gov.sp.fatec.saudacoes.Main

A opção --module-path é seguida de uma lista de diretórios que contém os módulos não integrantes do JDK/JRE; enquando a opção -m deve ser seguida pelo nome do módulo e da classe que deve ser executada, mas sempre usando o separador '/'.
O resultado deve ser como segue:
Olá Jigsaw!
A listagem dos módulos disponíveis, conforme o passo 10, deve ser semelhante à figura que segue.
O resultado da aplicação simples construída, executada como indicado no passo 12, deve ser como na próxima figura.

Este exemplo mostrou como construir uma aplicação simples, constituída de um único módulo, com o novo sistema de modularização da plataforma Java.

Aplicação e Módulo-Recurso

Uma situação bastante mais típica é uma aplicação constituída de vários módulos. Nestes casos, sempre existe um módulo principal e outros módulos que se comportam como recursos do módulo principal.

Nesta parte do exemplo, criaremos uma aplicação, ainda no estilo clássico do "Hello World", mas que utiliza uma classe auxiliar de um pacote residente em um outro módulo, ou seja, a aplicação utiliza um módulo adicional como recurso.

1.
Navegue para o diretório inicial (Jigsaw).

2.
Crie novos subdiretórios para o novo pacote jandl.tecnopode.
md src\jandl.tecnopode\jandl\tecnopode

3.
Navegue para o subdiretório src\jandl.tecnopode\jandl\tecnopode.
cd src\jandl.tecnopode\jandl\tecnopode

4.
Neste subdiretório crie o arquivo Saudacoes.java com o conteúdo que segue.
package jandl.tecnopode;

public class Saudacoes {
   private String message;

   public Saudacoes() {
      this("Ola Jigsaw!");
   }

   public Saudacoes(String msg) {
      setMessage(msg);
   }

   public String getMessage() {
      return message;
   }

   public void setMessage(String msg) {
      message = msg;
   }

   @Override
   public String toString() {
      return getMessage();
   }
}

4.
Navegue para o subdiretório que denomina o pacote (src\jandl.tecnopode):
cd ..\..

5.
Neste subdiretório crie o arquivo module-info.java, que é o descritor do módulo jandl.tecnopode, com o conteúdo que segue.
module jandl.tecnopode {
   exports jandl.tecnopode;
}

6.
Navegue para o diretório inicial (Jigsaw).
cd ..\..

7.
Compile os arquivos do novo pacote e do descritor do módulo.
(Forneça os comandos que seguem numa única linha!)
javac -d modules\jandl.tecnopode
      src\jandl.tecnopode\jandl\tecnopode\Saudacoes.java
javac -d modules\jandl.tecnopode
      src\jandl.tecnopode\module-info.java

É possível compilar tudo junto:
javac -d modules\jandl.tecnopode
      src\jandl.tecnopode\jandl\tecnopode\Saudacoes.java
      src\jandl.tecnopode\module-info.java

8.
Verifique se o novo módulo é observável pela JVM com:
java --module-path modules --describe-module jandl.tecnopode

9.
Navegue até o diretório do subpacote src\br.gov.sp.fatec.saudacoes.
cd src\br.gov.sp.fatec.saudacoes\br\gov\sp\fatec\saudacoes

10.
Neste subdiretório crie o arquivo Main2.java, que corresponde a nova aplicação, com o conteúdo que segue.
package br.gov.sp.fatec.saudacoes;
import jandl.tecnopode.Saudacoes;

public class Main2 {
   public static void main(String[] args) {
      Saudacoes sds = new Saudacoes("Ola novamente Jigsaw!");
      System.out.println(sds);
   }
}

Observe que a classe Saudacoes, do novo pacote jandl.tecnopode, é importada como usualmente feito.

11.
Navegue para o diretório inicial (Jigsaw).
cd ..\..\..\..\..\..\..

12.
Compile a nova aplicação (Main2.java).
(O comando abaixo deve ser fornecido em uma única linha!)
javac --module-path modules
      -d modules/br.gov.sp.fatec.saudacoes
      src/br.gov.sp.fatec.saudacoes/br/gov/sp/fatec/saudacoes/Main2.java
src\br.gov.sp.fatec.saudacoes\br\gov\sp\fatec\saudacoes\Main2.java:2: error: pac
kage jandl.tecnopode is not visible
import jandl.tecnopode.Saudacoes;
            ^
  (package jandl.tecnopode is declared in module jandl.tecnopode, but module br.
gov.sp.fatec.saudacoes does not read it)
1 error

O erro obtido se deve ao fato do módulo da aplicação não ler/importar o módulo recurso.

13.
Navegue para o subdiretório inicial do pacote br.gov.sp.fatec.saudacoes.
cd src\br.gov.sp.fatec.saudacoes

14.
Edite o descritor de módulo module-info.java como segue, para indicar a importação do módulo que contém os recursos necessários.
module br.gov.sp.fatec.saudacoes {
   requires jandl.tecnopode;
}

15.
Navegue para o diretório inicial (Jigsaw).
cd ..\..\

16.
Compile novamente a nova aplicação (Main2.java) e também o descritor de seu módulo.
(O comando abaixo deve ser fornecido em uma única linha!)
javac --module-path modules
      -d modules/br.gov.sp.fatec.saudacoes
      src/br.gov.sp.fatec.saudacoes/br/gov/sp/fatec/saudacoes/Main2.java
      src/br.gov.sp.fatec.saudacoes/module-info.java

17.
Execute a nova aplicação.
(O comando abaixo deve ser fornecido em uma única linha!)
java --module-path modules
      -m br.gov.sp.fatec.saudacoes/br.gov.sp.fatec.saudacoes.Main2

O resultado da nova aplicação é como o que segue.
Ola novamente Jigsaw!

Este segundo exemplo mostrou como construir uma aplicação ainda simples, embora mais realista, pois é constituída de um módulo que utiliza recursos de outro módulo. 

Na sequência serão exploradas outras possibilidade que exibem algumas das vantagens do novo sistema de modularização.

Empacotamento dos módulos

Até agora, a compilação dos módulos construídos gerou uma árvore de subdiretórios contendo o código binário das classes distribuídos em seus respectivos subdiretórios. Em nosso projeto o subdiretório Jigsaw\src contém a árvore do código fonte dos tipos pertencentes a cada um dos módulos criados, enquanto Jigsaw\modules contém a árvore do código binário dos respectivos tipos. Claramente esta estrutura é pouco adequada para distribuição do código das aplicações.

A ferramenta de linha de comando jar, que existe desde a primeira versão do Java, foi atualizada para possibilitar a criação de módulos, ou seja, permite empacotar os tipos e descritor de um módulo na forma de um arquivo JAR.

Convém criar um novo subdiretório no projeto para conter os módulos empacotados a partir do diretório inicial (Jigsaw).
md library

Para criar um módulo, use a ferramenta jar como segue:
(O comando abaixo deve ser fornecido em uma única linha!)
jar --create
    --file=library/jandl.tecnopode@1.0.jar
    --module-version=1.0
    -C modules/jandl.tecnopode .

A opção --create é autoexplicativa; --file determina o caminho e o nome desejado para o módulo que será criado; --module-version especifica a versão do módulo; -C indica o diretório onde existe a árvore do código binário do módulo.

jar --create
    --file=library/br.gov.sp.fatec.saudacoes@1.0.jar
    --main-class=br.gov.sp.fatec.saudacoes.Main2
    -C modules/br.gov.sp.fatec.saudacoes .

Aqui deve ser observado o uso da opção --main-class seguida do nome da classe principal do módulo (aquela que é executada por padrão).

A figura que segue ilustra o resultado do empacotamento dos módulo br.gov.sp.fatec.saudacoes e jandl.tecnopode.


Com o empacotamento, a distribuição de uma aplicação se resume ao envio dos módulos necessários, que podem ser usados em qualquer outra instalação do Java 9. Para executar a aplicação, basta fornecer:
java -p library -m br.gov.sp.fatec.saudacoes

A opção -p indica uma lista de diretórios que contém os módulos necessários; enquanto -m especifica o módulo que (classe principal) terá o início executado, como mostra a figura que segue.


A ferramenta jar também pode ser usada para descrever um módulo empacotado, como exemplificado nos comandos que seguem.

jar --describe-module --file=library/jandl.tecnopode@1.0.jar
jar --describe-module --file=library/br.gov.sp.fatec.saudacoes@1.0.jar


Criação de Imagem Executável da Aplicação

Uma novidade muito interessante do Java 9 é a possibilidade de criação de imagens executáveis (runtime images) de aplicações. Uma imagem executável contém uma JVM, os módulos específicos de uma aplicação e todas as suas dependências, inclusive as transitivas (decorrentes da execução), permitindo que a aplicação seja executada em qualquer ambiente compatível, independente destes possuírem ou não instalações compatíveis do Java.

A JVM provida numa imagem executável contém apenas os módulos necessários para a aplicação, ou seja, aqueles não utilizados não são inclusos, reduzindo seu tamanho, constituindo um ambiente customizado e independente, pois não requer a presença de um JRE ou JDK para sua execução.

Apenas a arquitetura do sistema deve ser compatível, ou seja, as imagens executáveis construídas para uma arquitetura específica de SO só podem ser utilizadas em tais SOs, tal como ocorre com programas executáveis gerados para o Microsoft Windows, que não são compatíveis com SO Linux e outros.

Ainda assim, a distribuição de uma imagem executável pode simplificar muito seu uso, pois seus usuário não precisam se preocupar com os pré-requisitos de instalação necessários.

O jlink é a nova ferramenta de linha de comando capaz de criar imagens executáveis, como no exemplo de uso que segue.
(O comando abaixo deve ser fornecido em uma única linha!)
jlink --module-path %JAVA_HOME%\jmods;library
      --add-modules br.gov.sp.fatec.saudacoes
      --output jigsawDemoApp

A opção --module-path é seguida pela lista de diretórios de módulos necessários (no caso o subdiretório jmods na instalação local do Java 9 e o subdiretório library do nosso projeto). A opção --add-modules indica o módulo da aplicação que será adicionado na imagem. A opção --output indica o subdiretório onde a imagem obtida será gerada. Note que as dependências do módulo br.gov.sp.fatec.saudacoes (ou seja, os módulos java.base e jandl.tecnopode) são automaticamente identificadas e adicionadas à imagem.

A imagem gerada terá a seguinte estrutura:
jigsawDemoApp
├───bin
│   └───server
├───conf
│   └───security
│       └───policy
│           ├───limited
│           └───unlimited
├───include
│   └───win32
├───legal
│   └───java.base
└───lib
    ├───security
    └───server

Em sua raiz existe um arquivo release que contém a versão do Java e os módulos inclusos na imagem executável. No diretório lib encontramos o arquivo modules com apenas 21.8MB, bem menor que o correspondente da JVM completa da versão 9.

Para executar a aplicação encapsulada na imagem executável, basta fornecer o comando que segue:
jigsawDemoApp\bin\java -m br.gov.sp.fatec.saudacoes/br.gov.sp.fatec.saudacoes.Main2

Nele utiliza-se a JVM da própria imagem, seguida da opção -m e da combinação do nome do módulo (br.gov.sp.fatec.saudacoes), do separador '/' e do nome da classe principal  da aplicação (br.gov.sp.fatec.saudacoes.Main2).

Também é possível solicitar que a ferramenta jlink gere um pequeno script de inicialização, mais fácil de ser usado. Para criar a imagem executável e também gerar tal script, o comando adequado é:
jlink --module-path %JAVA_HOME%\jmods;library
      --add-modules br.gov.sp.fatec.saudacoes
      --output jigsawDemoApp
      --launcher launch=br.gov.sp.fatec.saudacoes/br.gov.sp.fatec.saudacoes.Main2

Observe a adição da opção --launcher launch=<modulo>/>classePrincipal>.

A ativação da aplicação agora pode ser feita de maneira bem mais simples com:
jigsawDemoApp\bin\launch

Conclusões

Os exemplos deste post, embora muito simples, mostram como utilizar de maneira proveitosa o novo sistema de modularização do Java. Em sua primeira parte mostra como criar módulos (modules). Na segunda parte mostra como construir aplicações constituídas de vários módulos.

Além disso, estes exemplo permitem perceber como a distribuição de aplicações é simplificada tanto pelo uso de módulos, como pela criação de imagens executáveis (runtime images). Módulos podem ser distribuídos diretamente, permitindo o reuso em diferentes aplicações, funcionando como componentes. No entanto o uso dos módulos requerem um ambiente de execução Java  previamente instalado. Já a distribuição de imagens executáveis é muito conveniente, pois não requerem ambientes de execução pré-instalados, pois já contém uma JVM própria. Além disso, as imagens executáveis permitem a customização das JVM para aplicações específicas, o que é algo bem interessante.

Isto tudo permite afirmar que o aguardado projeto Jigsaw e seu novo sistema de modularização é, de fato, uma valiosa adição na plataforma Java!


Para Saber Mais


quarta-feira, 3 de janeiro de 2018

Java 9::Jigsaw, a nova modularidade da plataforma (Parte II)

Depois de mais de oito anos de trabalho, o projeto Jigsaw e o novo sistema de modularidade para a plataforma Java estreiam na versão 9, trazendo um grande conjunto de novas possibilidades para o desenvolvimento de software.
Desenvolvimento modular com Java 9
Desenvolvimento modular com Java 9
A parte I deste post abordou o conceito de modularidade e a especificação do novo artefato module trazida pelo Jigsaw.

Agora, na parte II, será discutida a implementação do Jigsaw na versão 9 do Java. Para finalizar este post, na parte III, temos um exemplo de construção de uma aplicação modular.

O JDK modularizado

Uma das queixas frequentes sobre a plataforma Java era o fato de sua API nativa ser constituída de um monólito de código gigantesco. Estamos falando do famigerado arquivo rt.jar (Java Runtime archive). Qualquer aplicação Java executada na versão 8 (ou anterior), requer que o rt.jar esteja disponível, pois nele residem todas as classes e interfaces padronizadas da máquina virtual. Como tal arquivo é grande, o trabalho da JVM para localizar e extrair qualquer tipo necessário para a aplicação em execução é, obviamente, mais demorado do que a execução destas mesmas tarefas em arquivos menores.

A versão do rt.jar localizada no subdiretório lib do JRE possuia 51,9MB no JRE 1.8.0_121. Já a versão armazenada no subdiretório jre\lib, do JRE incluso no JDK da mesma versão 1.8.1_121, tem 60.4MB. Ambos possuem mais de 19000 arquivos distintos.

Além da mencionada dificuldade no carregamento de tipos, o tamanho do rt.jar é proibitivo em aplicações destinadas a equipamentos que não sejam computadores, por exemplo, para dispositivos "vestíveis" (wearable devices) ou embutidos (embeded devices).

Outro problema, menos discutido, mas igualmente presente, é a inconveniente dependência cíclica, pouco intuitiva, existente entre alguns de seus elementos.

Como já visto, o ponto de partida do projeto Jigsaw foi a criação de um novo artefato module que, conforme a especificação da versão 9, é um arquivo JAR modular. Um arquivo JAR modular é um arquivo JAR que possui um descritor de módulo, module-info.class, no diretório raiz do arquivo JAR. Tal descritor é a forma binária da declaração de um módulo.

Uma das maiores tarefas do projeto Jigsaw foi dividir o arquivo rt.jar em um conjunto adequado de módulos, menores, interdependentes, mas sem dependências circulares. O resultado pode ser visto na figura que segue (que precisa ser ampliada - basta clicar - para que seus detalhes sejam observados).

Hierarquia dos módulos no Java 9

Na parte inferior da figura podemos ver o módulo java.base, o único que não depende de outros - que possui arestas de chegada. Todo e qualquer módulo criado lê (ou depende de) java.base, implícita ou explicitamente, de maneira similar a importação do pacote java.lang.

O módulo java.base exporta pacotes como java.lang, java.util, java.math etc., que são praticamente onipresentes em qualquer aplicação Java.

Os novos módulos são como novos componentes, carregados por meio de um modulepath (que substitui o antigo classpath), mais simples e mais eficiente. Um classpath típico lista os diretórios onde residem os pacotes, sem deixar claro quais são os pacotes necessários dentro de cada um dos diretórios indicados. Já um modulepath lista apenas os módulo necessários, reduzindo a incerteza em relação aos elementos necessários para uma aplicação.

Na versão 9 o JDK é tipicamente instalado num diretório jdk-9, que possui um subdiretório jmods que contém todos os módulos da API Java, resultado do trabalho de modularização do Jigsaw. O modulo java.base está contido no arquivo java.base.jmod que possui apenas 15.8MB. Os arquivos de extensão jmod tem formato compatível ao dos arquivos jar, ou seja, são uma espécie de arquivo compactado no formato ZIP. O tamanho total do subdiretório jmods é 116MB (maior que o antigo rt.jar). Além disso, existe um arquivo modules (sem extensão), no subdiretório lib, com 167MB, que condensa todos os módulos, e cuja existência é garantir a compatibilidade com as aplicações produzidas por versões anteriores ao Java 9.

Já a versão 9 do JRE, instalada num diretório jre-9, existe apenas o subdiretório lib, no qual existe o arquivo modules com 107MB, requerido para executar qualquer aplicação Java. 

A presença do arquivo modules, embora pareça recriar a situação anterior do rt.jar, é uma consequência da retrocompatibilidade garantida pelo Java 9 em relação às versões anteriores. Esta é a configuração default do JDK e do JRE nesta versão. Mas a grande diferença proporcionada pelo Jigsaw está naquilo que pode ser feito além da configuração padrão.

Com a modularização do JDK torna-se possível especificar quais módulos do Java Runtime serão usados, reduzindo o trabalho da JVM na localização de tipos (com menos módulos, menos tipos, menos trabalho no carregamento de classes). Assim, se a aplicação não usa componentes Swing, o módulo java.desktop não precisa ser incluído; se o suporte para Corba não é necessário, nada  de especificar java.corba; e assim por diante. Apenas o módulo java.base é essencial (por isso é carregado implicitamente).

Na prática, isto significa que o Java 9 torna possível customizar a JVM para conter apenas os módulos necessários a um conjunto específico de aplicações; até mesmo otimizando-o para uma única aplicação especial. Quando tal customização não é feita, a configuração default, de compatibilidade mais ampla, é garantida.

jlink

A nova ferramenta de linha de comando jlink permite que sejam escolhidos os módulos e dependências a serem inclusas em uma distribuição, com granularidade muito fina, unindo-os. Isto muito contribui para reduzir e controlar o tamanho das distribuições. 

Abaixo temos o formato típico da linha de comando do jlink, envolvendo o modulepath, os módulos inclusos e a indicação da saída.

> jlink --module-path <modulepath>
       --add-modules <module>[,<module>...]
       --output <path>

Com isto o jlink permite criar um arquivo modules completamente customizado para uma aplicação específica, o que permite otimizar a JVM para ambientes particulares. Dentre as várias opções do jlink é possível indicar o nível de compressão dos módulos, os serviços interligados, plugins, a lista de módulos observados, etc.

Um exemplo de uso do jlink é:

> jlink --module-path %JAVA_HOME%/jmods;projectMod
      --add-modules br.gov.sp.fatec.saudacoes
      --output saudacoesapp

Este comando cria uma imagem runtime que contém o módulo br.gov.sp.fatec.saudacoes, incluindo suas dependências transitivas (isto é, decorrentes de sua execução). O valor de --module-path é o caminho dos diretórios contendo os módulos previamente empacotados. Use ';' como separadores de diretório no Microsoft Windows e ':' no Unix/Linux. Assim, %JAVA_HOME%/jmods é o diretório que contém o módulo java.base.jmod (e os demais módulos padrão do JDK). O diretório projecMod, incluído no modulepath, é aquele que contém os demais artefatos, no caso, o módulo denominado br.gov.sp.fatec.saudacoes. A saída produzida, a imagem da aplicação, será armazenada no diretório saudacoesapp.

Além disso, o jlink permite também controle avançado sobre a ligação entre os módulos, com a possibilidade de escolhe entre ligação estática (static linking), que cria módulos maiores, mas mais rápidos; e ligação dinâmica (dynamic linking), que cria módulos menores, mas com mais tempo de carregamento maior.


Conclusões

O Jigsaw tem um papel central no Java, pois com ele se espera melhorar a modularidade, a eficiência e também a segurança da plataforma. Com ele torna-se possível criar aplicações mais escaláveis, leves, robustas e seguras.

A ambição maior do Jigsaw é incentivar o desenvolvimento de um ecossistema completo baseado na linguagem e na JVM, por meio de um software develpment kit (SDK) modular, para criar aplicações modulares com uso de ferramentas igualmente modulares.

Concretamente o Jigsaw permite solucionar o JAR hell (vide primeira parte do post); obter melhor encapsulamento e segurança entre pacotes e clientes destes pacotes; performance melhorada e tamanho reduzido do ambiente mínimo requerido para aplicações modulares.

Na próxima e última parte deste post será construída uma aplicação modular.

Para Saber Mais