Série 3 Refactoring e Manutenção de Software

Salve! Salve! Mas uma semana e estou aqui marcando presença com mais uma serie Refactoring.  Onde vou abordar como Refactoring influencia na manutenção de software e a opinião de alguns autores consagrados no mundo T.I pensam a respeito. Espero que gostem dessa ultima série refactoring.

Recomendo quem puder compre o livro do Fowler, realmente é um excelente livro.  E para os que não “curte”  livro inglês a tradução está de parabéns, eu tenho tanto o inglês quanto e português e fiz comparações de vários capítulos com a obra original e nada de erros grosseiros no processo de tradução.

Let’s GO…

Outros post da Série/Other post of the series

1.Refatoração

2.Vantagens/Desvantagens e Ferramentas

Summary

This article presents as a refactoring can contribute for maintenance of software. Refactoring help a develop software more fast because avert that the project of the system if damage, bettering the process of maintenance and optimization of the time spent in the developing. Last refactoring contributes for maintenance of the software.

Cenário Manutenção Software

Segundo Maia (2004), o custo e a complexidade de se manter um Software são amplamente reconhecidos. Estima-se que cerca de 50% do tempo de um engenheiro de Software é gasto com tarefas de manutenção e compreensão de código.

De acordo com Pressman (1995) a manutenção de Software pode ser responsável por mais de 70% de todo o esforço despendido por uma organização de Software. E essa porcentagem continua aumentando à medida que mais Software é produzido. Para este autor manutenção de Software é bem mais que “consertar erros”. Há quatro atividades que são levadas a efeito depois que o Software é liberado para uso. São elas:

-A primeira atividade de manutenção ocorre por que não é razoável prevenir que a atividade de testes do Software decorrerá todos os erros latentes num grande sistema de Software. E durante o uso de qualquer programa, erros ocorrerão e serão relatados ao desenvolvedor.

-A segunda atividade que contribuiu para uma definição de manutenção ocorre por causa da rápida mudança que é encontrada em cada aspecto da computação. Novos sistemas operacionais, novas gerações de hardware por exemplo.

-A terceira atividade quando um pacote de Software é bem-sucedido. À medida que o Software é usado, recomendações de novas capacidades de modificações em funções existentes e de ampliações gerais são recebidas dos usuários.

-A quarta atividade de manutenção ocorre quando o Software é modificado para melhorar a confiabilidade ou a manutenção futura, ou para oferecer uma base melhor para futuras ampliações.

O custo da manutenção de Software tem aumentado firmemente durante os últimos 20 anos. Durante a década de 1970, a manutenção era responsável por um índice entre 35% e 40% do orçamento de Software para uma organização de sistemas de informação. Esse valor pulou aproximadamente 60% durante a década de 1980. Se nada for feito para melhorar a manutenção, muitas empresas gastarão 80% de seus orçamentos de Software em manutenção. Quanto mais eficiente for à fase de manutenção do Software mais fácil é de mantê-lo. (Pressman, 1995)

Refatoração e Manutenção

A refatoração pode ser considerada uma técnica ou ferramenta de auxilio no desenvolvimento e manutenção, contribuindo para o tempo de vida do Software, já que o acréscimo de novas funcionalidades é de maneira fácil e rápida. (FOWLER, 2004)

Para Pressman (1995), quanto mais eficiente for à fase de manutenção do Software mais fácil é de mantê-lo.

Em seu livro Fowler diz que um sistema mal projetado normalmente precisa de mais código para fazer as mesmas coisas muitas vezes porque o mesmo código foi duplicado em diversos lugares diferentes. Quanto mais difícil é visualizar o projeto a partir do código, mais difícil será preservá-lo e mais rapidamente ele se desestruturará. A eliminação de código duplicado é um aspecto importante na melhora do projeto, sendo que reduzindo a quantidade de código faz uma grande diferença sobre a manutenção desse projeto.

Fowler (2004) defende que quanto mais código houver em um Software, mas difícil será modificar corretamente.

“[…] Reduzir a quantidade de código faz, todavia, uma grande diferença sobre a manutenção desse código. Quanto mais código houver, mais difícil será modificá-lo corretamente. Há mais código para ser entendido. Você altera trecho de código aqui, e o sistema não faz o esperado porque faltou alterar em outro lugar que faz a mesma coisa em um contexto levemente diferente […]”. (FOWLER, 2004, p. 54)

Sendo assim a refatoração ajuda a desenvolver Software mais rapidamente porque evita que o projeto do sistema se deteriore, melhorando o processo de manutenção e otimização do tempo gasto no desenvolvimento. Enfim refactoring contribui para manutenção do software.

Tem dúvidas por que usar a técnica de refactoring no ambiente de desenvolvimento?

Infelizmente a série de refactoring foi curta, mas aqui foi apenas o first time. Em breve venho com a segunda parte da série onde pretendo abordar outros pontos importantes referente à técnica de refactoring e apresentá-la a nível de código.  Recebi alguns emails perguntando a diferença entre Extreme Programming (XP) e Refactoring veja abaixo para quem dúvida a respeito das praticas:

XP

Uma metodologia que foi responsável pelo crescimento da visibilidade de aplicar refatoração foi Extreme Programming (XP). Uma das principais idéias Extreme Programming é que o desenvolvedor deve trabalhar em apenas um caso de uso por vez e assim deve projetar o Software para que fique coerente com o caso de uso em questão. Se um determinado caso de uso não ficou bem projetado, deve-se aplicar refatorações até que o caso de uso possa ser implementado de uma maneira coerente. XP é uma metodologia que é baseada em mudanças. Um dos principais pilares de XP é a continua e agressiva aplicação de refatorações. Sem elas, XP não funcionaria. (MAIA, 2004)

Reflexão:

Espero que a série refactoring tenha contribuído para a vida de você programador, desenvolvedor etc. E que a partir de “ontem” essa técnica venha fazer parte do ambiente de desenvolvimento.

O ponto que me chamou atenção, é que as empresas de T.I cobram varias siglas ao fazer um processo de admissão, porém de 10 vagas que consultei nos maiores sites de empregos de T.I nenhuma delas “queriam saber se você programador, desenvolvedor sabe algumas das boas práticas de desenvolvimento”.

O máximo que foi possível encontrar nas vagas era Design Patterns. Achei isso preocupante. Mesmo que uma empresa tenha uma política interna de desenvolvimento é importante que essa política seja baseada em algo, por exemplo: na técnica de refactoring, XP. Não considero boas práticas as empresas que definem:

– Aqui somente usamos IDE X

– E todas as variáveis de instancia são private e deve ser escrita da forma Y

– Os acessos as variáveis somente por método

Um bom programador já DEVE já saber isso por natureza. Já que essa nomeação vem lá da O.O

O que quero chamar atenção para as empresas de T.I um engenheiro, um arquiteto etc. Que antes de cobrar tantas siglas (JSF,JSP, SERVLET etc) analise também a questão se esse profissional sabe alguma das boas práticas de desenvolvimento a nível de código. Desenvolver uma aplicação e colocar para funcionar é apenas 20% do projeto os outros 80% do trabalho vai estar na manutenção (se o desenvolvedor morrer ou sair da empresa o projeto pode falhar se ninguém entender o código desenvolvido).

Recentemente peguei uma aplicação de um “bom programador” (meu amigo) que ela atendia todos os pré-requisitos do cliente (para o cliente melhor aplicação do mundo, já que atendia todas as suas necessidades). Porém fui analisar o código (apenas por curiosidade) meu deus, quase tinha um infarto. De tanta duplicidade, modificadores aplicados de forma indevida, e os tamanhos de cada comentário daria um livro.

Tenham bastante cuidado com isso. Eu acredito que no futuro teremos vagas somente para “Reestruturar Software sem mudar o comportamento observável”.

Abraço! E até próximo post!

Referências

Fowler (2004)

Pressman, R. S. (1995). Engenharia de Software (3ª ed.).

MAIA, P. H. (2004). REFAX:Um arcabouço para desenvolvimento de ferramamentas de refatoração baseado XML. Programa de Pós Graduação em Ciência da Computação . Ceará, Fortaleza: UFC

Série 2 Refactoring: Vantagens/Desvantagens

Salve! Salve! Dando continuidade a série Refactoring, hoje vou abordar as vantagens/desvantagens e as ferramentas que temos disponíveis. Quero chamar atenção no primeiro tópico do post: Vantagem da Refatoração. Quis fazer um pouco diferente ao invés de pegar as vantagens de refactoring e tentar convencê-lo de usar ou apenas mostrá-las. Acabei fazendo diferente, não vou dizer de forma direta as vantagens de refactoring você como bom programador vai refletir sobre as abordagens dentro do tópico, e daí percebam onde entra o porquê de você adotar refactoring e seus respectivos benefícios no seu ambiente de desenvolvimento.

O motivo que fiz isso é que alguns/muitos profissionais de T.I sabem da existência de refactoring, sabem das vantagens que assistiu em alguma palestra ou leu um artigo na web/revista, porém após ter visto nada mudou em sua vida como programador. E eu sou apenas mais um transmitindo aquilo que ele já viu várias vezes.

O que quero é que você programador/analista etc. após ler reflita, pegue um código seu e se pergunte será preciso refatorar meu software?

Let’s GO…

Summary

This article presents the vantages/disadvantage and the tool that have available for refactoring. The list of the tool is in the end this article.

There are four parts that became the program hard of work. See below:

– Program that is hard of read the level of code

– Program that have the logic duplicate

– Logic conditional: program with logic conditional complex is hard of work.

The tool for refactoring help the project letting more elastic.

Vantagens da Refatoração

Refatorar é o processo de pegar um programa em produção e agregar a ele valor, não por meio da alteração de seu comportamento mais dando qualidades que nos permitem continuar desenvolvendo rapidamente. É preciso ter programas fáceis de ler a nível de código e que tenham a lógica especificada em apenas um lugar.

Programas têm dois tipos de valor: o que eles fazem por você hoje e o que podem fazer por você amanhã, na maior parte das vezes quando estamos desenvolvendo um Software focalizamos no queremos que o programa faça hoje.” (Beck,2000)

Nas palavras de Beck [2000 apud Fowler, 2004, pg.58] “Se você consegue fazer hoje o trabalho de hoje, mas o faz de uma maneira na qual possivelmente não conseguirá fazer amanhã o trabalho de amanhã, é considerado perdido”. Para este autor refatorar é uma maneira de sair dessa situação. (se achou confusa a citação acima leia com mais calma, parece frase de índio então busque ler pausadamente buscando o gancho e perceba o que está entre linhas sobre afirmação do Dr. Beck. Frases de Drs. são assim mesmo rsrs)

Beck (2000), identifica quatro partes que torna os programas difíceis de trabalhar/modificar:

Programas que são difíceis de ler à nível de código

– Programas que tem lógica duplicada

– Inclusão de novas funcionalidades: Programas que para inclusão de novas funcionalidades, requerem a alteração de código existente, são difíceis de modificar

– Lógica condicional: Programas com lógica condicionais complexas são difíceis de modificar.

Existe ou não existe vantagem de aplicar refactoring?

Desvantagem

Segundo Fowler (2004) não há experiências em quantidade suficiente para definir onde as limitações se aplicam a técnica de refatoração. Abaixo apresento algumas das áreas citadas por Fowler onde este autor considera que são difíceis (isso não quer dizer que é impossível) de aplicar a técnica de refatoração.

Banco de dados: É uma área problemática para refatoração. A maioria das aplicações comerciais são altamente acopladas ao esquema do banco de dados que as suporta. Esse é um motivo pelo qual bancos de dados são difíceis de modificar. O outro motivo é a migração de dados, onde alterar o esquema do banco de dados lhe força a migrar os dados, o que pode ser uma tarefa longa e pesada. (Observe que há profissionais, cientistas trabalhando nesse caso, confira a matéria sobre o tema no blog Visão ágil)

Alterando interface: Um problema com a interface é se estiver sendo usada por código que não é possível encontrar e alterar. Tendo assim se torna uma interface publicada onde não é mais possível alterá-la com segurança e sim apenas modificar a chamada nos métodos que a invocam e isso dificulta o processo de refatoração. Se uma refatoração alterar uma interface publicada tem que conservar tanto a interface antiga quanto a nova e isso leva ao caminho da duplicação de código.

Linguagens não orientadas a objetos: São mais difíceis de reestruturar, pois fluxos de controle e de dados são fortemente interligados e por causa disso as reestruturações são limitadas a nível de função ou bloco de código.

Há outras áreas citadas por Fowler que você encontra no livro do autor.

Ferramentas para Refatoração

Mas Camilo eu tenho uma duvida, vou ter que refatorar na “mão grande”?

R- Também. Mas não é a única opção.

Você já imaginou refatorando um programa com 2 mil linhas de códigos? É complicado e pode atrasar o projeto certo? Para isso temos as algumas ferramentas automatizadas para refatoração. Antes de apresentar as ferramentas que dão suporte à linguagem Java, veremos o que alguns autores dizem a respeito do uso dessa técnica e no final temos o objetivo geral das ferramentas.

Refatorar com suporte de uma ferramenta automatizada é diferente da refatoração manual. Primeiro que a refatoração à mão consome muito tempo em programas grandes. (Fowler, 2004)

As ferramentas automatizadas diminuem o risco de erros e inconsistência no código, além de poupar um grande trabalho em se tratando de sistemas com centenas ou milhares de linhas de códigos. (Beck,2000)

Segundo Roberts (1997 apud Fowler, 2004, pg.342) com as ferramentas de refatoração automática o projeto se torna mais elástico, já que alterá-lo é muito menos custoso, sendo assim estender o projeto adicionar flexibilidade no futuro sem grandes custos. Para este autor o principal propósito de uma ferramenta de refatoração é permitir ao programador, refatorar código sem ter que testar novamente o programa.

Abaixo a relação das ferramentas de refatoração para Software Java:

List tool:

-XRefactoring (xref-tech)

– IntelliJ IDEA (IntelliJ IDEA)

-IBM Visual Age for Java (IBM)

Abraço a todos! Vou ficando por aqui espero que tenham gostando e até próximo post (o ultimo da série Refactoring).

Thanks!

Referências

IntelliJ IDEA. (s.d.). http://www.jetbrains.com/idea/index.html

IBM. (s.d.). http://www-142.ibm.com

xref-tech. (s.d.). http://www.xref-tech.com/

Fowler (2004)

Serie 1:Boas Práticas com Refactoring

Olá Pessoal! Hoje vou falar sobre uma técnica que alguns conhecem  apenas teoricamente, uns usam constantemente e outros que nunca ouviram falar. A  nova série do blog é Refactoring. Ops!O que é  isso?  

Refactoring é o modo de você mudar a estrutura interna de seu software sem alterar seu comportamento observável. Você usa essa técnica quando você quer melhorar a legibilidade do código do software. Mas vale lembrar que Refactoring não usada para consertar erros e sim para prevenção. Com ou sem Refactoring seu software deve funcionar da mesma forma de antes ter aplicado a técnica.

 Nem todos os programadores conhecem  ou sabem aplicar a técnica refactoring, devo confessar que não conhecia a técnica antes de novembro/2007. Mas após uma discussão com um amigo sobre o assunto me interessei sobre o tema, dei inicio aos estudos que virou tema de minha monografia e que passou ser uma pratica constante no desenvolvimento de software. Tornou-se uma mania ao ver um código bagunçado e refatorá-lo. Vale salientar que não sou um experts na técnica me considero um mero estudante e curioso com a técnica. 

Espero que gostem da série Refactoring e que ela venha contribuir no seu ambiente de desenvolvimento de software. 
Let’s GO…

Summary

This article presents the technical of refactoring. Refactoring is one process of the restructure the system without changes your operation. Second Fowler (2004) refactoring into the software more easy of understand and change. One user or a programmer not is capable of say that something changed in the software. The technical of the refactoring help in the legible of code. For Fowler the refactoring is one element-key in process of the developing of software.

Sites/Livros:

http://www.refactoring.com

Livro Fowler

Introdução

Algumas profissionais de T.I acreditam que desenvolver um software é sentar na frente do computador e sair codificando. Já alguns acreditam que desenvolver software deve seguir o mesmo processo de linha de montagem de carro como  no filme tempos modernos.

Mas  bons desenvolvedores de software sabem que esse não  é o caminho correto. Desenvolver software requer planejamento e esse pode ser alterado de acordo com o ciclo de vida do software então o ambiente de desenvolvimento não é algo estático. Quando nasce um novo requisito uma parte do projeto ou todo o projeto passa a sofrer alterações e para executar esses novos requisitos é necessário planejar. Senão você desenvolvedor pode entrar em buraco sem saída com o software.

Para não entramos nesse “buraco” temos a refatoração que vem auxiliar no aperfeiçoamento do código-fonte minimizando as chances de novas falhas serem introduzidas no projeto. Refactoring contribuir para processo evolutivo do software, pois as técnicas de refatoração quando aplicada  de forma correta ao software aumenta consideravelmente seu tempo de vida útil, sua extensibilidade e modularidade.

Definição

Refatoração é o processo de reestruturar o sistema sem alterar suas funcionalidades. Mas Fowler (2004) vai um pouco mais além. Segundo este autor refatoração torna o Software mais fácil de entender e modificar. Para ele, apenas as mudanças feitas para tornar o Software mais fácil de entender são consideradas refatoração. A refatoração não altera o comportamento observável do Software. Esse ainda executa a mesma função de antes. Qualquer usuário seja ele final ou programador não é capaz de dizer que algo mudou.

Fowler defende que a refatoração é um elemento-chave no processo de inteiro desenvolvimento de software. O autor vai além e afirma que um bom projeto vem antes mesmo de sua codificação. Desenvolver software requer planejamento. É importante dizer que  refatorar é um “alicate de prata” que ajuda a manter o código seguro, porém a técnica de refatoração não cura todos os problemas no desenvolvimento de Software, mas é uma ferramenta valiosa.

Refatoramos para:

– Melhorar o projeto do Software: um projeto sem refatoração termina por se deteriorar à medida que as pessoas alteram o código e sem uma compreensão total do projeto, do código, acaba desestruturando. A refatoração é uma forma para estruturar o código;

– Tornar o Software mais fácil de entender a nível de código eliminado códigos duplicados;

– Encontrar falhas rapidamente, a partir do melhoramento do código;

– Programar mais rapidamente;         

Quando Refatorar

Para Fowler (2004) decidir quando começar a refatorar e quando  parar é tão importante quanto à mecânica de refatoração. Explicar como apagar uma variável de instancia ou criar uma hierarquia é questões simples, porém tentar explicar quando deve fazer, não é algo tão consolidado. Em seu livro Fowler apresenta os problemas que podem ser resolvidos por uma refatoração, mas cabe ao analista de sistemas, programador, desenvolvedor a própria percepção sobre quantas variáveis de instâncias são demais, quantas linhas de código em um método são excessivos.  Abaixo vou apresentar algumas das dicas que considerei importantes citadas Kent Beck um dos criadores da Programação Extrema (Extreme Programming – XP), afirma que refatoração deve ser utilizada quando o “código cheira mal” (do inglês “bad smells in code”).

A refatoração deve acontecer quando…

Código duplicado: Quando tem o mesmo código em mais de um lugar, dificultando a manutenção e aumentando o numero de falhas durante a manutenção do Software.

Método longo: Quando um método tem muito código. Quanto maior for o método, mais difícil é entendê-lo.

Classes grandes: Quando uma classe tem muita coisa a fazer, normalmente há existência de muitas variáveis de instâncias.

Comando switch: Os comandos switch essencialmente levam a duplicação. É comum encontrar o mesmo comando switch espalhado por diversos lugares do mesmo programa.

Comentários: Os comentários nos conduzem ao código ruim. Comentários que estão no código sem explicar o porquê, são considerados supérfluos.

Nesse momento você pode estar se perguntado: “Tudo bem vi quando refatorar  e  onde a técnica pode contribuir para meu software, mais o por que de  fazer tudo isso?”

Veja…

Segundo Maia (2004) o custo e a complexidade de se manter um Software são amplamente reconhecidos. Estima-se que cerca de 50% do tempo de um engenheiro de Software é gasto com tarefas de manutenção e compreensão de código e que ao longo das últimas três décadas mais de 60% dos custos de desenvolvimento de Software das organizações foram gastos com manutenção. Refatoração é o processo de mudar um Software de tal forma que melhore a estrutura interna sem, contudo alterar o comportamento externo. Portanto, é uma forma disciplinada de re-organizar o código, minimizando as chances de introduzir erros. Refatorar tem a vantagem de melhorar a estrutura do código, facilitando o reuso e diminuindo o tempo gasto com tarefas de manutenção. O termo refatoração é aplicado a sistemas orientados a objetos; para outros paradigmas de programação esse mesmo processo é descrito como reestruturação.

Percebeu o por quê?

Bom pessoal! Vou ficando por aqui, o assunto Refactoring é um pouco extenso e não pretendo abordar todo em um único post para não ficar cansativo. No próximo mostrarei mais sobre Refactoring  falando sobre as vantagens /desvantagens e as ferramentas  disponíveis.

Um abraço a todos!

Referencias:

Fowler

Maia, P. H. (2004). REFAX:Um arcabouço para desenvolvimento de ferramamentas de refatoração baseado XML. Programa de Pós Graduação em Ciência da Computação . Ceará, Fortaleza: UFC

Série SCJP:Polimorfismo e Genéricos

Salve!Salve! Mais uma semana e estou aqui  com mais uma série Revisão SCJP. Conforme falei na semana passada, hoje o assunto é: polimorfismo e genéricos  onde veremos como eles trabalham juntos e  as diferenças em relação ao uso  de polimorfismo com array sendo assim é importante você programador Java saber essas diferenças. Somente um detalhe não esquecer que  genéricos está apenas a partir do Java 1.5.

Aproveitando, venho informá-los  que essa será a ultima coluna da serie Revisão SCJP, na próxima coluna abordarei outros assuntos, mas não precisa fazer essa cara de triste por que a série revisão SCJP voltará de vez em quando basta acompanhar o blog! O motivo é para não ficarmos abordando um único assunto.

Let’s go  fight!

Pré-Requisito

Instalação Java 1.5/superior

– Revisão SCJP  Genérico/Generics

Summary

This article presents as use polymorphism and generics. The use polymorphism with generics there is one big different when use polymorphism and array. You cannot create one collection as below:

List<Animal> l = new ArrayList<Dog>();

Same that Dog extends Animal you cannot do this in collections. Because is permit only create collection of same type. However, you can add one object of other type as long as this object extends the class of the type of your collection. See below:

class Animal{}

class Dog extends Animal{}

ArrayList<Animal> la = new ArrayList<Animal>();

la.add(new Animal());

la.add(new Dog());

This code compiles and execute because you have one collection of the same type and add one object that extends the type of collection.  Is very important that you have attention with question about polymorphism and generics in the exam because they can to get you confuse. In the end this article there is one link for download of the one list with several example of generics and polymorphism do download this list, analysis the code and after test each example.

Polimorfismo e Genéricos

Ao usar polimorfismo com genéricos é importante ter bastante atenção e “esquecer” temporariamente a regra que  é aplicada a um Array. Por exemplo:

Posso ter um Animal[] array, que pode aceitar qualquer tipo ou subtipo de Animal, mas em Conjuntos a coisa é diferente isso não funciona. Veja:

import java.util.ArrayList;

import java.util.List;

class Animal{}

class Dog extends Animal{}

class Poli{

public static void main(String agrs[]){

List<Animal> l = new ArrayList<Dog>();

l.add(new Animal());

l.add(new Dog());

}}

 Esse código não compila. Mas por quê?

Por que  você está tentando criar um conjunto que aceita tipos diferentes onde deveria ser de um único tipo. É normal você achar que deveria compilar já que Dog extends Animal, caso isso fosse um array de Animal não haveria problema algum mais  quando se trata de conjuntos o polimorfismo opera diferente. 

Eu costumo dar um exemplo bem pratico veja:

“Se você compra uma caixa de maçã(É-UM Fruta) e levar berinjela(É-UM Fruta) dentro dela, será que você ficaria furioso quando abrisse a caixa? Então o compilador(feirante) ele evitar esse transtorno (ao cliente) permitindo que dentro da caixa de maça fique apenas maçã, mais nenhuma fruta.”

import java.util.ArrayList;

import java.util.List; 

class Animal{}

class Dog extends Animal{} 

class Poli{

public static void main(String agrs[]){

Poli p = new Poli();

ArrayList<Animal> la = new ArrayList<Animal> ();

la.add(new Animal());

la.add(new Dog()); //aceita porque  Dog extends Animal

}} 

Coringa <?>

O uso do coringa permite receber qualquer tipo. Quando usa o coringa e extends estamos dizendo que é permitido receber qualquer  class que é subtipo daquela class ou uma interface que implementa aquela classe. Mas você não pode adicionar nada ao conjunto. Veja o que não compila:

import java.util.*;

class Carta{}

class Coringa extends Carta{}

class Jogo{

public void cha(List<? extends Carta> car){

car.add(new Carta());          } 

public static void main(String [] agrs){

Jogo j = new Jogo();

List<Carta> list = new ArrayList<Carta>();

list.add(new Carta());

j.cha(list);

}} 

Não compila porque usei < ? > sendo assim estou dizendo ao compilador que pode receber um conjunto de qualquer subtipo, porém JAMAIS adicioná-lo ao conjunto, nem que seja do mesmo tipo. 

Basta alterar essa parte do código para compilar veja:

public void cha(List<? extends Carta> car){

/* observe que não foi adicionado nada a minha lista*/ 

<? super tipo> 

Como temos o extends temos também uma palavra chave super para a notação <?> o qual permite que você adicionar ao conjunto apenas o que está acima daquele tipo.

import java.util.*;

class Carnaval{}

class Banda extends Carnaval{}

class Bloco extends Banda{}

class Chi{ 

public void carna(List<? super Banda> band){

band.add(new Banda());

band.add(new Bloco());} 

public static void main(String [] agr){

Chi ch = new Chi();

List<Carnaval> lis = new ArrayList<Carnaval>();

ch.carna(lis);}} 

Observe que meu método aceita qualquer tipo acima de Banda, porém não posso passar  Bloco porque eu informei que seria super e nao extends a Banda. 

Outro o ponto a observar aqui é que meu método aceitou  um argumento do tipo diferente. 

Está confuso? Experimente fazer essa alteração: 

List<Bloco> lis = new ArrayList<Bloco>();

E veja que o código não compila. Já que o método diz que não é permitido receber nada que não for super a Banda.

<?> – Qualquer Tipo: Permite receber qualquer tipo dog, cat, etc. Porém não posso adicionar(add) nada ao conjunto. 

import java.util.*;

class QuaCor{

public void ch(List<?> li){//nada de adicionar algo aqui} 

public static void main(String agr[]){QuaCor qc = new QuaCor();

List<Integer> li = new ArrayList<Integer>();

List<QuaCor> list = new ArrayList<QuaCor>();

qc.ch(li);

qc.ch(list);}}

Onde não posso usar coringas: 

Na  criação dos objetos: List<?> f = new ArrayList<? extends Animal>(); 

Usar coringas ? apenas:  Argumentos ,variáveis e tipos de retornos. 

List<? extends Animal> li = new ArrayList<Dog>(); 

ArrayList<?> list = new ArrayList(); 

ArrayList<? extends Girafa> g = new ArrayList<Gir>();

//não posso add nada aqui g.add(new Gir()); não compila

<Object>(aceita apenas Object) é diferente de <?> (aceita qualquer coisa). 

Quando você usa <?> pode receber qualquer tipo mais quando usa Object pode receber apenas Object se usar <? extends Object> pode ser qualquer tipo: Dog, Cat, Integer. Porém sem adicionar ao conjunto. 

Bom pessoal! Espero que tenha gostado da coluna e aprendido um pouco como funciona o polimorfismo com genéricos, no inicio acontece uma pequena revolução no cérebro já que com array o uso do polimorfismo é bem mais fácil. Mas com genéricos não é difícil a questão é se acostumar e ficar atento as regras e lembrar que o segredo de genéricos está no tipo do conjunto. No link abaixo deixei uma lista de classes  para você ficar ligado nas pegadinhas para o exame e erros que você pode cometer ao desenvolver uma aplicação usando genéricos e polimorfismo.

Um abraço e até a próxima!
Download – lista de classes

 

 

 

 

 

 

 

Serie SCJP:Genérico/Generics

Salve! Salve! Pessoal! Mais um post da série Revisão SCJP. No ultimo post falei sobre Conjuntos/Collection e aproveitando o ritmo vou falar hoje sobre Generics/genéricos que foi adicionado ao Java 5 e consta no exame 310-055. Nessa coluna as explicações serão mais a nível de código então fique atento aos comentários.
Aos estudantes SCJP se liguem nas pegadinhas que pode constar no seu exame.
Let’s GO…

Pré-Requisito

– Instalação Java 1.5/superior

Last Column Java – Imasters  /Ultima Coluna Java – Imasters:  

Instalando e configurando ambiente JEE Netbeans 6 

Summary

This article presents a theory and practice about Generics. Generics are one subject that is present in the exam 310-055 and there are several questions about this subject. When I did my exam I did, about seven questions with generics and some lots difficult.
Generics serve for specific the type of Collection.
In the Java 5, you can specific that type of object your Collection can to get. I spoke Object, pay attention for not confuse with type primitives. Check the example
Ex.1
below.
The
Ex.2 not compile because I try to add object different this Collection, see: 
ist.add(“camilo”);
It is impossible, because we have one Collection of the type Integer. 

Genéricos

Os genéricos ele servem para especificar o tipo de conjunto. Ou seja, manter a proteção dos objetos para aquele determinado conjunto. “Procure não colocar maça na caixa de uva”. 

No Pré-Java 5  não era possível informar que tipo de conjunto. Veja:  

Ex.1

List l = new ArrayList();

l.add(“74”);

l.add(new Dog(“dd”));

//recebe qualquer coisa

 No Java 5 você especificar que tipo de objeto seu conjunto pode receber. Eu falei OBJETO cuidado para não confundir com tipos PRIMITIVOS.

 Ex.2

List<Integer> ist = new ArrayList<Integer>();

ist.add(99);

ist.add(44);

ist.add(“camilo”);//erro de compilação não pode receber String somente Integer

 Para o exame/sua vida como programador você não pode esquecer os pontos abaixo referente a genéricos:

 -Se usar Java 5 com pré-Java sua proteção vai para o “saco do lixo”, ele aceita qualquer coisa pensando que ta recebendo o tipo especifico.

 – Os erros com GENÉRICOS  são de compilação e não tempo de execução a não ser um quando acontece Cast que não seja possível.

 -Para a JVM em tempo de execução você está usando o pré-java, pois senão lançaria uma exceção.

 -O compilador ele que fica encarregado de verificar se esta tudo ok.

 -Compilar códigos com avisos não quer dizer erro de compilação. O compilador apenas avisa que ali a algo inseguro.

 -As proteções(tipos) nos conjuntos NÃO EXISTEM EM TEMPO DE EXECUÇÃO

 -Os tipos dos conjuntos(<Integer>, <Double> etc.) são destruídos em tempo de execução.

 Vejamos alguns exemplos:

//uso um tipo especifico mais passo para um não especifico proteção já era

import java.util.*;

class TestBad{

public static void main(String [] agrs){

List<Integer> list = new ArrayList<Integer>();

list.add(4);

list.add(9);

list.add(10);

Inserter in = new Inserter();

in.insert(list);

System.out.println(list);

}}

class Inserter{

void insert(List list){

list.add(new Integer(42));

list.add(new String(“camilo”));

list.add(new Double(3.9));

}}

/*está confuso? Por que adicionou uma String ao ArrayList de Integer ?
Observe que a classe que o
método insert recebe qualquer objeto e adiciona  à lista os desenvolvedores tiveram que manter isso, para que evitasse uma mudança desastrosa, para aos pré-java*/ 

/*mas é importante ter cuidado com isso no exame ele vai confundir ao infinito e  ficar brincando com Java 5 e pré-Java 5. Genéricos  é um bom assunto para brincar */ 

O código acima  compila com avisos já que temos um conjunto não seguro. Se o método da classe Inserter for modificado para void insert(List<Integer> list) o código não compila, pois somente posso ter conjunto Integer e estou adicionando ao meu conjunto outros objetos.

 A idéia de conjunto o interessante é pensar como um Barril experimente colocar dentro de um barril de polvora(Integer) algo que gere Calor(Double) eu acho que explode e você? (não compila).

 Vamos a outro exemplo:

import java.util.*;

class ConverPre{

public static void main(String agrs[]){

List lit = new ArrayList();

lit.add(58);

System.out.print(lit + ” “);

}}

No pré Java 5 isso não funcionava já que o Boxing não é feito de forma automática. Mas se encontrar uma questão assim no exame 310-055 pode marcar que compila e executa.

 Nesse ultimo exemplo apresento como pode acontecer uma exceção no caso de genéricos:

 import java.util.*;

public class GeneriList { 

//esse metodo nao quebra nenhuma regra 

static void adde(List lt){ 

lt.add(new String(“neto”));} 

public static void main(String[] args) { 

ArrayList<Integer> lis = new ArrayList(); 

lis.add(10);

lis.add(50);

adde(lis); 

System.out.println(lis); 

for(Integer it : lis){ 

int z = it; 

System.out.println(z);}}} 

Ele lança uma exceção por ter adicionado algo indevido no meu conjunto e quando fui retirar os elementos do conjunto achei que somente tinha Integer, porém fui enganado e vi uma exceção. 

A proteção foi  para o saco quando o método adde (pre-java 1.5) foi misturado com código que usa Java 5, mais o maior erro foi adicionar lt.add(String). Se fosse um Integer não teríamos problema.

 A exceção ocorre  tentar passar uma String para um Integer. O meu for espera um Integer do meu conjunto e não uma String.

 Uma situação como acima pode acontecer com um programador que não conhece as regras  de genéricos e se na equipe de desenvolvimento não contar com algum programador com o conhecimento a resolução para essa exceção pode consumir alguns minutos/horas e quem sabe gerar uma gambiarra.

 Essas são as questões faz parte do grupo das mais difíceis do exame e como a Sun não dar colher de chá a maioria das questões que envolver genéricos vai ser nesse nível (pelo menos as minhas foram).

A dica é: “Estude para aprender e para passar no exame!” 

Vou ficando por aqui! E na próxima coluna vou continuar o assunto de genéricos abordando polimorfismo e genéricos como eles se entendem? Aguarde até o próximo post.

Um abraço a todos! E até próxima!