Vamos iniciar os estudos da disciplina de Programao III com o objetivo de ampliar o nvel de profundidade sobre o tema programao. Em Programao I voc teve contato com o paradigma da Orientao a Objetos, agora iremos usar a estes conhecimentos em assuntos com Socket/Thread, Programao Web e Aplicaes Distribudas. Estes so temas de aplicao prtica nas organizaes e no desenvolvimento de softwares comerciais envolvendo a programao em rede na intranet ou internet. A conduo do material que voc ir ler busca passar conceitos que esto associados com a programao envolvendo a troca de mensagens pela rede e tambm aumentar o seu amadurecimento na construo de softwares usando o paradigma da Orientao a Objetos. Este contedo vai te ajudar bastante a fazer a integrao de aplicaes e entender como usar tcnicas de programao mais avanadas pautadas em reuso.....
Similar ao mdulo de Programao I, todo o contedo aqui elencado estar organizado em uma ordem de complexidade pensada para te ajudar ao mximo no aprendizado, ou seja, para cada contedo iremos fazer atividades de baixa, depois media e por fim, alta complexidade. Com essa estratgia espera-se que o leitor v ganhando confiana e maturidade na disciplina programao. Bons estudos e leia essa matria diversas vezes, idealmente,
Indicao de Leitura
Este material usa como base vrias referncias tendo como a principal o livro Cornell, Gary; Horstmann, Cay. Core Java 2: Recursos Avanados (vol.2.). So Paulo, SP: Makron Books, 2001.
no como uma obrigao, mas sim como um grande prazer. Lembrem-se quando estamos motivados somos capazes de superar qualquer desafio.
Bons Estudos Os autores
1. Consideraes Sobre Reutilizao de Software (Exemplo do Componente de Colees)
O desenvolvimento de projetos de software no uma tarefa fcil. Os projetos, geralmente, tm que ser robustos, atuar sobre problemas complexos e estar implantados em curto prazo (time-to-market).
A reutilizao reconhecida como um importante modo para se alcanar um aumento na produtividade em projetos de software, pois possibilita agregar funcionalidades pr-existentes na produo de novos software. Ressalte-se tambm a possibilidade de programadores iniciantes criarem software complexos atravs da utilizao de padres de projetos descritos por programadores mais experientes.
Alm do mais, a reutilizao de pedaos de software garante uma maior qualidade ao projeto, visto que os blocos a serem reutilizados j esto testados e validados por uma ou mais aplicaes. Portanto, o direcionamento no desenvolvimento de um projeto de software para que no se construa nada que j exista e que possa ser reutilizado.
Entretanto, necessrio produzir software genricos e extensveis que possam ser aplicados a uma gama de aplicaes. Ao longo dos anos, muitas metodologias surgiram na engenharia de software com o intuito de reduzir a complexidade e aumentar a produtividade no desenvolvimento. A Orientao a Objetos reconhecida hoje como o principal paradigma para atender a essa reduo da complexidade.
1.1 Reutilizao e Orientao a Objetos
Reutilizao de software o grande desafio dos projetistas de software. A engenharia de software vem evoluindo substancialmente para ir ao encontro a essa necessidade. Dentre as diversas metodologias existentes, Orientao a Objetos (OO) o principal paradigma para a construo de software reutilizvel. Apesar do grande sucesso do paradigma OO, nem sempre os resultados, em relao a reutilizao, so obtidos de forma fcil.
As vantagens da Orientao a Objetos, como paradigma para a reutilizao de software, so bem conhecidas. As abstraes podem corresponder s coisas do domnio do problema o O nvel mais natural. o mais fcil comunicar-se com o usurio ou domain expert na linguagem dele. Os mesmos objetos existem em todas as fases e uma notao nica (objetos) facilita portanto a integrao entre fases de desenvolvimento (passar de uma fase para a outra). mais fcil entender o domnio do problema quando este quebrado em pedaos: gerenciamento da complexidade atravs da modularizao. O mesmo pode ser dito no domnio do computador (projetando e programando com objetos). A abstrao controla a complexidade (escondendo algo atravs da separao da interface e da implementao). A encapsulao facilita as mudanas (atravs do isolamento). A hierarquia (grafo de herana) permite uma melhor reutilizao.
Um dos mecanismos da Orientao a Objetos para alcanar a reutilizao de cdigo o uso de biblioteca de classes que encapsulam determinadas funcionalidades que possam ser reutilizadas. Embora classes sejam unidades de cdigo reutilizveis, uma classe para cumprir sua funcionalidade, geralmente, tem dependncias com outras classes. Para a realizao de tarefas complexas necessrio que um grupo de classes trabalhem conjuntamente, caracterizando assim, um componente de software.
O conceito de componente de software pode ser entendido como uma composio de classes que juntas formam uma unidade para cumprir certas responsabilidades. Componentes devem possuir uma interface pblica para a comunicao com os blocos de cdigo externos. Eles tm como principal caracterstica o funcionamento como `caixas pretas, onde o desenvolvedor no precisa, necessariamente, conhecer os detalhes de sua implementao.
Atravs do uso de componentes, a reutilizao popularizou-se. Um exemplo clssico so as ferramentas RAD (Rapid Application Development) grficas (Visual Basic, Delphi, Centura, etc), que fornecem componentes visuais aplicveis nas construes de interfaces grficas. Os componentes visuais (VBX, OCX, etc) disponveis nessas ferramentas proporcionam um aumento na produtividade de desenvolvimento de sistemas comerciais.
Alm da reutilizao de cdigo, existem outros tipos de reutilizao. Por exemplo, a reutilizao de projeto atua no somente no patamar de cdigo, como tambm nos projetos conceitual e lgico.
1.2 Exemplo do uso de Componente (Collecions Java)
Naturalmente objetos em uma aplicao esto relacionados. Uma forma de associao a hierarquia de objetos que representada atravs da herana entre Classes. Assim, se uma classe Poento3D herda de uma classe Ponto, pode-se afirmar que um objeto de Ponto3D est abaixo na hierarquia em relao a um objeto do tipo Ponto.
Outra forma de associao so as referncias ou relacionamentos. Os relacionamentos determinam a forma de associao entre os objetos. O relacionamento entre uma classe Empregado uma classe Departamento indicar como os objetos dessas duas classes se relacionaro. Por exemplo, pode-se enunciar que um Empregado trabalha em um somente um Departamento e que em um Departamento podem trabalhar vrios Empregados. Existem alguns tipos de associao que so estruturais tambm conhecidos de composio. Quando um objeto responsvel por outros objetos ou composto por outros objetos tem-se um tipo de associao denominada de agregao. Por exemplo, um Circulo composto por dois Pontos que representam o seu centro. Assim, quando se enuncia que um objeto parte-de tem-se a ocorrncia de composio ou agregao. Existem dois tipos de agregao simples ou composta. A agregao simples mantm a semntica de composio parte-de, mas o objeto pode ser compartilhado, ou seja, fazer parte-de mais de um objeto. A agregao composta somente um objeto possui os objetos agregados. Uma forma fcil de fazer a diferena entre agregao simples e composta que na agregao composta os objetos agregados esto no mesmo ciclo de vida do objeto que os agrega. Por exemplo, um objeto Pedido composto por Itens, caso o Pedido encerre o seu ciclo de vida os Itens tambm sero encerrados. A composio de objetos um tipo de relao muito utilizada em projetos dessa natureza. Como no mundo real onde os objetos so compostos por outros objetos, na orientao a objetos isto no diferente. Na prtica observa-se que em projetos OO o uso de composio ocorre quase quem 100% dos projetos.
O conceito de componente de software entendido como uma composio de classes que juntas formam uma unidade para cumprir certas responsabilidades. Componentes devem possuir uma interface pblica para a comunicao com os blocos de cdigo externos (no confundir interface homem mquinas, ou seja, telas, menus com interface de um componente que a forma padronizada de comunicao com o mesmo). Eles tm como principal caracterstica o funcionamento como caixas pretas, onde o desenvolvedor no precisa, necessariamente, conhecer os detalhes de sua implementao. Esta diretiva permite a reduo da complexidade no produo de um software visto o desenvolvedor se abstrai da complexidade do algoritmo interno do componente. Outro ponto relaciona-se com a qualidade do cdigo encapsulado no componenete, pois como o bloco de cdigo usado em diversos projetos por principio este cdigo j esta homologado e bem testado. Assim, atravs da componentizao e dos conceitos de Programao Orientada a Objetos possvel a construo de projetos com alto grau de reutilizao e compartilhamento de cdigo, gerando uma reduo no ciclo de desenvolvimento e facilitando as futuras manutenes corretivas e evolutivas.
Para a melhor absoro da prtica associada composio veremos uma introduo sobre colees em Java. Ressalta-se que o contedo que ser apresentado nesta seo no esgota o assunto, assim para um maior grau de aprofundamento no tema recomendam-se leituras complementares. Antes de detalhar a temtica de colees importante entender porque este assunto est to associado como composio. Para compormos objetos com outros necessrio saber como constituir as relaes entre eles. Quando um objeto composto por somente um objeto de uma outra classe o mapeamento feito atravs de uma associao ou referencia. De forma aplicada necessrio que a classe que composta por outra possua um atributo do seu tipo. Por exemplo, se um cliente tem um endereo forma de mapeamento na classe Cliente ter um atributo do tipo endereo. Quando temos uma relao de uma classe com n objetos de outra classe a forma de mapeamento atravs de um atributo multivalorado. Por exemplo, se uma Agenda est associada com n objetos contatos da classe Contato a forma de mapeamento a criao na classe Agenda de um atributo multivalorado com uma coleo de contatos, ou seja, este atributo ter n referencias para objetos do tipo contato. A figura x apresenta graficamente os dois tipos de composio entre objetos.
Figura 1: Representao grfica da relao de composio entre objetos.
Para a implementao de atributos multivalorados pode-se utilizar vetores como, por exemplo, ilustra a figura 1. Neste caso o nosso atributo multivalorado a varivel c que pode referenciar at trs objetos do tipo conato.
Apesar deste tipo de implementao nos possibilitar a criao de atributos multivalorados, o esforo para desenvolver todos os algoritmos de insero, remoo, alterao, recuperao e ordenao de objetos muito grande. Assim, vamos usar colees que um conjunto de bibliotecas de classe e interfaces disponveis no java que nos permite reutilizar algoritmos para a composio de grupos de objetos. De forma sucinta colees (tambm chamado de container ) um objeto que agrupa mltiplos objetos. As colees so usadas para armazenar, recuperar e manipular dados na memria primria. Para isso, existem vrios tipos de colees que devem ser usadas de acordo com o problema a ser resolvido. (por exemplo ArrayList, Vector, HasMap, etc)
Figura 2: Diagrama de hierarquia de interface de Colees em Java.
A seguir so explicadas as principais interface do componente
Collection: Interface para tratar um grupo de objetos. Implementaes de Collection podem permitir elementos Duplicados ou no e Ordenadas ou desordenados. A linguagem java no prove nenhuma implementao para est interface. Existem somente implementao para as subinterfaces mais especificas como Set e List. O tipo Collection utilizado para passar colees como parmetro e manipular colees de forma mais genrica;
Set: Colees que no podem ter elementos duplicados. SortedSet um Set que mantm os elementos em ordem descendente. Exemplo de Implementao -> HashSet;
List: So colees que podem ter elementos duplicados. Listas podem ser acessadas por um index inteiro (posio). Exemplo de Implementao -> Vector, ArrayList;
Map: Objetos da coleo so mapeados por chaves. No podem ter chaves duplicadas. SortedMap semelhante ao SortedSet - Mantm um Map em ordem descendente. Exemplo de Implementao -> HashMap.
Para melhor entendimento da estrutura do componente de colees so apresentadas as classes TesteList e TestMap que ilustram o uso do componente em um mtodo main. Como sugesto voc deve colocar estes dois exemplos para funcionar no seu ambiente e fazer o exerccio do anexo I. Estas duas classes s funcionam com com a implementao de IF_Contato e Contato. Na classe Contato o mtodo equals fundamental para os mtodos contais, indexOf funcionarem corretamente.
public interface IF_Contato {
public String getNome();
public String getTelefone();
public void setNome(String nome);
public void setTelefone(String telefone);
}
public class Contato implements IF_Contato {
private String nome; private String telefone;
@Override public String getNome() { // TODO Auto-generated method stub return this.nome; }
@Override public String getTelefone() { // TODO Auto-generated method stub return this.telefone; }
@Override public void setNome(String nome) { // TODO Auto-generated method stub this.nome = nome; }
@Override public void setTelefone(String telefone) { this.telefone = telefone; // TODO Auto-generated method stub
} public String toString(){ return "Nome:" + this.nome + " Telefone:"+ this.telefone; } public boolean equals(Object o){ Contato c = (Contato)o; return this.telefone.equals(c.getTelefone());
} public static void main(String args[]){ IF_Contato[] c = new IF_Contato[2]; c[0]= new Contato(); c[0].setNome("A"); c[0].setTelefone("3344-9090");
c[1]= new Contato(); c[1].setNome("B"); c[1].setTelefone("9093-8990");
System.out.println(c[0].equals(c[1]));
} }
public class TesteList { public static void main(String args[]){
ArrayList lista = new ArrayList(); IF_Contato[] c = new IF_Contato[3]; c[0]= new Contato(); c[0].setNome("A"); c[0].setTelefone("3344-9090");
c[1]= new Contato(); c[1].setNome("B"); c[1].setTelefone("9093-8990");
c[2]= new Contato(); c[2].setNome("X"); c[2].setTelefone("8877-9898"); //Adicionado elementos em um List lista.add(c[0]); lista.add(c[1]); lista.add(c[2]); //Listando os objetos da coleo System.out.println(lista); //Recuperando o objeto da primeira posio da lista IF_Contato tempContato = (IF_Contato) lista.get(0); System.out.println(tempContato.getNome()); //Recuperando um contato pelo telefone IF_Contato tempContato1 = new Contato(); tempContato1.setTelefone("9093-8990");
int i = lista.indexOf(tempContato1);
System.out.println(lista.get(i)); //Verificando se um contato existe na lista System.out.println(lista.contains(tempContato1)); //Removendo Contato lista.remove(2);
System.out.println(lista); //Percorrendo sequencialmente os contatos Iterator it = lista.iterator(); while (it.hasNext()){ IF_Contato c3 = (IF_Contato) it.next(); System.out.println(c3); } } }
public class TesteMap { public static void main(String args[]){
HashMap lista = new HashMap();
IF_Contato[] c = new IF_Contato[3]; c[0]= new Contato(); c[0].setNome("A"); c[0].setTelefone("3344-9090");
c[1]= new Contato(); c[1].setNome("B"); c[1].setTelefone("9093-8990");
c[2]= new Contato(); c[2].setNome("X"); c[2].setTelefone("8877-9898"); //Adicionando contatod na Map
System.out.println(lista); //Recuperando Contatos pela Chave IF_Contato tempContato = (IF_Contato) lista.get(new String("3344- 9090")); System.out.println(tempContato.getNome()); //Verificando se uma chave j existe na lista System.out.println(lista.containsKey("3344-9090")); //Removendo Contato lista.remove("8877-9898"); //Imprimindo todos os elementos da coleo System.out.println(lista); //Percorrendo elementos sequencialmente de uma coleo //Iterator it = lista.values().iterator(); Collection collection = lista.values(); Iterator it = collection.iterator(); while (it.hasNext()){ IF_Contato c3 = (IF_Contato) it.next(); System.out.println(c3); }