[Pesquisar este blog]

quarta-feira, 7 de fevereiro de 2018

POO::Fundamentos-10-Pacotes e Namespaces

POO-F-09-Getters & Setters POO-F-11-Autorreferência this
A medida que a quantidade de código necessária para o desenvolvimento de um sistema aumenta, também cresce a possibilidade de que sejam criadas muitas classes com propósitos específicos. Para organizar melhor o código é conveniente separar as classes conforme seu propósito, organizando grupos funcionais que, no futuro, poderão ser mais facilmente compartilhados. Estamos falando dos pacotes e dos namespaces [4][6][7].

Pacotes

No Java é possível agrupar um conjunto de classes por meio da definição de um pacote (de classes). Os pacotes são implicitamente criados com o uso da palavra reservada package na construção de classes, pois seus emprego indica que a classe pertence a um pacote específico [4][7]. A diretiva package deve ser utilizada como primeira linha de um arquivo-fonte Java:

package exemplo;
public class Ex1 { /* implementação da classe */ }

Os pacotes também podem possuir subpacotes (subdivisões) indicados assim:

package exemplo.divisao;
package exemplo.divisao.outradivisao;

A divisão das classes de um projeto em pacotes é uma estratégia de modularização interessante, pois provê o agrupamento de classes semelhantes, facilita sua distribuição e, permite o reuso destes conjuntos.

No Java, as regras de nomenclatura sugerem que os pacotes devem utilizar apenas nomes em letras minúsculas, sendo recomendado que pacotes comerciais utilizem o nome reverso do domínio das empresas, das organizações ou dos indivíduos que detêm seus direitos, tais como:

package br.com.novatec.jgp3;
package br.anchieta.si.jandl;
package br.edu.fatecjd.ads.peter;

Os prefixos java e javax estão reservados para denotar pacotes pertencentes à API Java, não sendo permitido seu uso. A figura abaixo ilustra a organização dos pacotes do Java. Lá é possível localizar os pacotes:

  • java.lang, que contém as classes fundamentais do Java;
  • java.util, com classes e interfaces utilitárias;
  • java.io, com classes e interfaces destinadas à entrada e saída;
  • javax.swing, que contém componentes para interfaces GUI.



Diretiva import

Para utilizar as classes pertencentes a um pacote é empregada a diretiva import, no início do arquivo-fonte Java, para indicar quais pacotes e classes serão necessários. Por exemplo:

// importa APENAS a classe ArrayList do pacote java.util
import java.util.ArrayList;
// importa TODAS as classes do pacote java.util
import java.util.*;

A importação de todas as classes de um pacote com * (asterisco) não produz qualquer efeito negativo, como aumento do tamanho do código ou performance inferior [7], sendo apenas uma simplificação permitida ao programador. No entanto é recomendada a importação nominal das classes, a qual evita ambiguidades quando pacotes diferentes possuem classes com o mesmo nome (por exemplo, List, dos pacotes java.awt e java.util).

A importação não é obrigatória, assim é possível fazer uso das classes por meio da qualificação completa de seus nomes, ou seja, indicação do package (pacote) e do nome da classe nos locais de sua utilização, como segue:

// uso da classe JFrame do pacote javax.swing
javax.swing.JFrame janela = new javax.swing.JFrame("Janela");

// uso da classe ArrayList do pacote java.util
java.util.ArrayList lista = new java.util.ArrayList();

No entanto, a importação é vantajosa por melhorar a legibilidade do código:

// importação da classe
import javax.swing.JFrame;
// uso da classe
JFrame janela = new JFrame("Janela");

// importação da classe
import java.util.ArrayList;
// uso da classe
ArrayList lista = new ArrayList();

Namespaces

No C# (e também no C++), classes e outras declarações podem ser organizadas em conjuntos independentes que coexistem em um mesmo programa, dividindo o escopo global em outros menores, denominados namespaces [6][11].

Um namespace é um bloco de escopo denominado [9], ou seja, um espaço declarativo identificado, cujas definições permitem agrupar conjuntos de classes, objetos e métodos sob um nome.

Podemos declarar um novo bloco de escopo denominado utilizando a palavra reservada namespace assim:

namespace identificador {
  // bloco do sub-escopo (ou do namespace)
}

O identificador do bloco de escopo denominado é semelhante ao utilizado por variáveis, métodos e classes. Neste bloco podemos ter a definição de classes, estruturas e funções bem como a declaração de variáveis ou objetos. Um namespace simples pode ser definido assim:

namespace POO { // sub-escopo ou namespace POO
  long a;
  double b;
  class XMP {
     :
  }
}

Como a modularização é um dos aspectos fundamentais para o desenvolvimento bem sucedido de grandes sistemas, os namespaces são particularmente úteis para realizarem a divisão do escopo global em seções logicamente organizadas, mantendo uma separação conveniente entre as definições contidas nestes sem impedir sua utilização, pois um namespace não implica em restrições de acesso [6].

A diretiva using (semelhante ao import do Java) possibilita 'conectar' o escopo presente a um namespace específico, permitindo o acesso direto a seus elementos sem a necessidade de sua qualificação completa.

Assim, poderíamos ter:

// indicação de namespace desejado
using POO;

// uso da classe XMP sem qualificação completa.
XMP objeto = new XMP();


Considerações finais

O uso de pacotes ou de namespaces é uma boa prática de programação, já consagrada, que permite a divisão dos elementos de um sistema em módulos que podem ser melhor organizados e convenientemente empregados no desenvolvimento de outros sistemas. Além disso, o próprio agrupamento permite uma melhor compreensão dos elementos presentes, facilitando sua correta utilização.

POO-F-09-Getters & Setters POO-F-11-Autorreferência this

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.
[11] WATSON, K.; NAGEL, C.; PEDERSEN, J.H.; REID, J.D.; SKINNER, M.; WHITE, E.. Beginning Microsft Visual C# 2008. Indianapolis: Wiley Publishing, 2008.