DevMedia -Polimorfismo em ação.pdf

Embed Size (px)

Citation preview

  • 13/3/2014 DevMedia - Verso para impresso

    http://www.devmedia.com.br/websys.5/webreader_print.asp?cat=6&artigo=4781&revista=impressao_106#a-4781 1/17

    DevMedia - Verso para impresso

    Polimorfismo em ao

    Tcnicas e aplicao deste poderoso recurso da POO

    De que se trata o artigo

    Este artigo abordar um dos mais poderosos recursos de programao, item essencial na

    bagagem tcnica de todo bom desenvolvedor: o polimorfismo. Abordaremos, ao longo do

    texto, os conceitos que caracterizam as quatro tcnicas existentes, dando ao leitor o

    conhecimento necessrio para entender como o recurso aplicado nas bibliotecas e

    plataformas que utiliza no seu dia-a-dia, bem como de aplicar nas suas prprias

    implementaes.

    Em que situao o tema til

    Este tema til para todo profissional que atue no desenvolvimento de solues

    computacionais, principalmente aquelas desenhadas sob a luz do paradigma da orientao a

    objetos, em que o recurso do polimorfismo pode ser utilizado em sua plenitude. Embora

    praticamente todos os exemplos do artigo tenham sido desenvolvidos em Java, os conceitos e

    tcnicas demonstrados podem ser aplicados em qualquer linguagem de programao

    orientada a objetos.

    Algumas tcnicas de polimorfismo que veremos, como a de sobrecarga, podem inclusive ser

    adotadas em linguagens que no seguem o paradigma da orientao a objetos.

    Resumo Devman

    Muito se fala sobre polimorfismo e sua importncia para sistemas construdos,

    principalmente, sobre o paradigma da orientao a objetos. Entretanto, o foco dado a este

    conceito to importante , geralmente, parcial, e nem todas as tcnicas so conhecidas na

    profundidade necessria por uma parcela significativa de desenvolvedores. Este artigo

    apresentar de forma um pouco mais ampla cada um dos quatro formatos em que este

    conceito se apresenta, com exemplos prticos que complementam toda a teoria.

    Polimorfismo um termo que se originou do grego e significa vrias formas. A semntica do

    mesmo preservada quando transportado para o universo da programao de computadores.

    Atravs de tcnicas que veremos ao longo do artigo, possvel que criemos estruturas

    suficientemente genricas ao ponto de serem utilizadas em vrios contextos, tornando o

    cdigo-fonte final mais enxuto, legvel e manutenvel.

    Embora possamos observar polimorfismo tambm em linguagens estruturadas, no

    paradigma orientado a objetos que o conceito realmente ganha fora e aplicado em sua

    plenitude. Inmeros padres de projeto se beneficiam desta tcnica, dentre os quais podemos

  • 13/3/2014 DevMedia - Verso para impresso

    http://www.devmedia.com.br/websys.5/webreader_print.asp?cat=6&artigo=4781&revista=impressao_106#a-4781 2/17

    destacar o Abstract DAO, Abstract Factory, Template Method, Strategy, Observer e

    Composite. Mecanismos de tratamento de excees e eventos em praticamente todo

    framework, bem como o desenvolvimento de plug-ins, so itens altamente beneficiados pelo

    emprego das tcnicas polimrficas. De Swing/AWT a GWT e JavaServer Faces, passando por

    JPA, Hibernate, Struts, Spring e tantos outros, encontramos polimorfismo por todos os lados.

    No raro encontrarmos, em fruns renomados da web, profissionais de Tecnologia da

    Informao buscando explicaes mais detalhadas a respeito do polimorfismo e

    recebendo respostas como a transcrita a seguir, retirada de um desses canais: polimorfismo

    polimorfismo, no existem tipos de polimorfismo; motivao suficiente para a escrita deste

    artigo, em que abordaremos todas as caractersticas e roupagens deste conceito fundamental.

    O polimorfismo classificado em duas categorias, sendo que cada uma se ramifica em duas

    tcnicas. Veremos, neste artigo, exemplos da aplicao de cada uma, seguida de uma

    discusso a seu respeito. Esperamos que o leitor tenha uma experincia construtiva durante a

    leitura deste material, reciclando conceitos e aprendendo outros, levando para o seu dia-a-dia

    todas as prticas aqui abordadas.

    Antes de iniciarmos, verifique a Tabela 1, que resume as quatro abordagens existentes,

    tratadas a seguir em maiores detalhes. Todo o cdigo ser apresentado em Java (salvo uma

    das vertentes da tcnica de polimorfismo por sobrecarga, que ser exibida em C++), embora

    possam ser facilmente aplicadas a outras linguagens orientadas a objetos, como Objective-C

    ou C#.

    [abrir imagem em janela]

    Tabela 1. Resumo das quatro principais tcnicas de polimorfismo.

    O polimorfismo ad hoc A traduo literal para o termo ad hoc, que tem sua origem no latim e to utilizado por

    profissionais de computao, para isto ou, ainda, para esta finalidade. Na prtica, o termo

    usado para tudo aquilo que foi projetado para atender a uma demanda pontual, no

    genrica. Em outras palavras, tcnicas ad hoc sero sempre aquelas para ataque a

    necessidades pontuais.

    Esta categoria abrange duas tcnicas, que so conhecidas como coero (tambm chamado

    de casting) e sobrecarga. Ao longo desta seo, exploraremos cada uma em maiores

    detalhes.

    Polimorfismo por coero

    O significado literal do termo coero, na lngua portuguesa, ato ou efeito de obrigar/forar.

    E exatamente isto que acontece quando empregamos esta tcnica no desenvolvimento de

    sistemas computacionais: foramos um objeto a vestir uma roupagem especfica. Isto muito

    comum em casos em que precisamos definir um modelo genrico que seja, depois, redefinido/

  • 13/3/2014 DevMedia - Verso para impresso

    http://www.devmedia.com.br/websys.5/webreader_print.asp?cat=6&artigo=4781&revista=impressao_106#a-4781 3/17

    especializado por outras classes de objetos.

    Para que isso seja possvel, o template/padro construdo utilizando apenas tipos

    suficientemente abstratos (a partir de interfaces ou ainda classes abstratas), do qual

    se derivam/especializam diversos tipos de objetos de acordo com a necessidade.

    Como tudo o que est relacionado a desenvolvimento de software, tudo ficar muito mais

    claro analisando um exemplo. As Listagens 1, 2 e 3 apresentam um primeiro caso de estudo

    da tcnica de polimorfismo por coero, e sobre ele que discutiremos nestes prximos

    pargrafos. Uma classe intitulada Produto utilizada para manipular, em tempo de execuo,

    dados referentes a produtos. A persistncia e recuperao de registros referentes a produtos

    junto ao banco de dados local do dispositivo mvel (este cdigo de uma aplicao mvel

    para a plataforma Android) esto definidas em uma classe de nome DaoProduto.

    Entretanto, este aplicativo no trata apenas de produtos, mas de outros tipos de elementos

    (como clientes, vendas, dentre outros).

    Isto exige a criao de outros tipos de objetos de acesso a dados para trabalhar

    exclusivamente com essas outras entidades, e o comportamento esperado para cada um

    desses novos objetos o mesmo que verificamos na classe DaoProduto. Nesses casos,

    necessria uma padronizao de comportamento, obtida atravs da criao de um contrato

    por meio da classe abstrata a que demos o nome de GenericDAO.

    Nesta classe so implementados todos os comportamentos comuns a qualquer DAO, e

    apenas declarados os comportamentos que variaro de um DAO para outro.

    Como o tipo de elemento que cada DAO manipular diferente, o contrato precisa definir

    parmetros genricos o suficiente para funcionar para todos os tipos de entidades do universo

    a ser atingido.

    A classe GenericDAO utiliza o tipo genrico java.lang.Object para representar todos os tipos

    de registros processados por classes de objetos de acesso a dados. Como esta a classe

    mais genrica da API do Java, qualquer classe de objetos criado em nossa aplicao uma

    extenso dela.

    At aqui tratamos apenas da generalizao, pois estamos discutindo a definio do contrato

    a ser seguido por todos os DAO especialistas. Mas como ficaria o tratamento do objeto em

    cada classe especialista? Para isso, ser necessria uma verificao para garantir que o

    objeto passado realmente o tipo tratado por aquele objeto.

    A verificao do tipo da instncia realizada, no cdigo da Listagem 3, por meio do

    qualificador instanceof, que retorna um valor booleano. Caso o tipo do objeto seja realmente

    aquele tratado pelo DAO, o prximo passo utilizar o recurso de coero, em que o objeto

    volta a ser tratado por seu tipo original.

    Resumindo, utilizamos generalizao para definirmos o padro comportamental para objetos

    de acesso a dados, e para isso trabalhamos com o tipo mais genrico possvel para definir a

    instncia que representa o registro a ser manipulado. Empregamos, depois, especializao

    para implementar cada um dos DAO, e o tipo genrico deu espao, por meio da tcnica de

    coero, ao tipo de registro manipulado pelo DAO em questo.

    Um exemplo de aplicao de polimorfismo por coero observado na prpria API do Android

    pode ser observada na recuperao de instncias de servios da plataforma. A Listagem 4

    mostra como recuperar referncias para servios de carregamento dinmico de leiautes

    (android.view.LayoutInflater) e localizao (android.location.LocationManager). A

    implementao deste mtodo retorna as instncias dos servios respectivos em uma

    roupagem genrica (java.lang.Object), o que nos obriga a forar a tipagem do objeto

    retornado para o servio desejado.

    Polimorfismo por sobrecarga

  • 13/3/2014 DevMedia - Verso para impresso

    http://www.devmedia.com.br/websys.5/webreader_print.asp?cat=6&artigo=4781&revista=impressao_106#a-4781 4/17

    Vamos, agora, falar do segundo tipo de polimorfismo ad hoc: a sobrecarga.

    E, para entendermos na prtica esta tcnica, vamos utilizar uma das funes disponveis na

    API da classe android.content.Context. Toda tela em uma aplicao Android representada

    por uma atividade (android.app.Activity), e a definio do contedo visual dessas telas pode

    ser realizada de duas maneiras:

    1. Atribumos atividade um identificador que representa um leiaute declarado em um arquivo

    XML, que posteriormente interpretado e convertido em objetos (widgets) associados entre si;

    ou seja: a estrutura declarada no arquivo XML ser utilizada para se criar o contedo grfico

    da atividade, em tempo de execuo;

    2. Criamos programaticamente e atribumos atividade uma instncia da classe

    android.widget.View.

    visvel que estamos falando de duas maneiras distintas de se definir o contedo visual de

    uma atividade. Entretanto, o nome do mtodo exatamente o mesmo para os dois cenrios:

    setContentView(). E o que muda? Muda o tipo do parmetro passado.

    No primeiro caso, passado um valor numrico e inteiro, gerado e mantido em uma classe de

    nome R (de resources); j no segundo caso, o parmetro do tipo android.widget.View, que

    representa genericamente qualquer elemento grfico, seja este um container ou um widget.

    Veja, abaixo, a assinatura dos dois mtodos comentados at agora:

    android.content.Context - setContentView(int resId);

    android.content.Context - setContentView(View view).

    Esta a tcnica da sobrecarga de mtodos na prtica: mantemos o nome de um determinado

    mtodo e definimos, para ele, dois formatos distintos de utilizao, representados pelos

    parmetros exigidos em cada assinatura. A Listagem 5 apresenta um exemplo da utilizao de

    sobrecarga de mtodo mencionada acima. Trata-se da primeira implementao mencionada

    na lista acima, em que um componente do tipo android.view.View representado por um valor

    numrico e inteiro.

    Ainda na Listagem 5, no segundo exemplo, o mesmo mtodo sobrecarregado para receber

    como parmetro de entrada um objeto do tipo android.view.View diretamente. O resultado final

    o mesmo: carrega-se, para a atividade (android.app.Activity) em questo, a interface grfica

    que ela se encarregar de renderizar na tela do dispositivo mvel.

    H tambm um segundo modelo de sobrecarga, que o de operadores.

    Em Java, esta opo est disponvel apenas para uso, o que significa que no possvel

    sobrecarregarmos operadores para necessidades especiais que, eventualmente, verificarmos,

    sendo possvel somente o uso das sobrecargas j definidas na plataforma.

    Um exemplo tpico e muito comum de sobrecarga de operadores em Java o recurso de

    concatenao de texto, fazendo com a que soma de dois objetos do tipo java.lang.String

    resulte em um novo objeto de texto cujo valor o texto do primeiro objeto emendado ao texto

    do segundo.

    O motivo de sobrecarregarmos operadores usar o mesmo conjunto de operadores j

    conhecidos e oferecidos pela linguagem de programao em questo (com os quais o

    desenvolvedor j est familiarizado, portanto) para desempenhar funes diferenciadas em

    contextos que no sejam aqueles estabelecidos como padro.

    Existe um material bastante denso a respeito de sobrecarga de operadores em livros

    renomados no universo da computao.

    A Listagem 6 apresenta um exemplo de utilizao da sobrecarga do operador de soma para

    objetos do tipo java.lang.String. Na sequncia, na Listagem 7, podemos observar um exemplo

    de sobrecarga de operadores em C++.

  • 13/3/2014 DevMedia - Verso para impresso

    http://www.devmedia.com.br/websys.5/webreader_print.asp?cat=6&artigo=4781&revista=impressao_106#a-4781 5/17

    Alguns operadores, mesmo quando aplicados a tipos primitivos, possuem tratamentos

    especiais dependendo do tipo de dado manipulado.

    Em C++, por exemplo, embora aparea de forma transparente para o desenvolvedor, o

    operador de soma opera de maneiras distintas para elementos dos tipos int, double e float.

    Interessante e desconhecido por boa parte dos desenvolvedores mais novos, uma

    sobrecarga normalmente ignorada, pois, de maneira geral, o operador funciona muito bem

    para todos os tipos mencionados. A sobrecarga de operadores na linguagem C++ realizada

    escrevendo-se, inicialmente, uma definio de funo (contendo cabealho e corpo,

    normalmente). A regra para o nome da funo o primeiro detalhe: deve ser prefixada com a

    palavra operator, seguida do operador que ser sobrecarregado. Portanto, o nome da funo

    definida para sobrecarregar o operador de soma seria operator+.

    Analisando o cdigo da Listagem 7, verificamos que se trata de uma sobrecarga do operador

    de extrao de contedo de uma stream de entrada de dados (istream). Ou seja: estamos

    alterando o comportamento do operador >>, transformando o contedo lido na stream de

    entrada em um padro arbitrrio.

    Logo no cabealho, possvel percebermos que definida a assinatura da funo de

    sobrecarga. Esta funo recebe dois parmetros, sendo um do tipo istream e o segundo do

    tipo PhoneNumber. Este ltimo representa um contato telefnico. Ele ser lido e ter o seu

    contedo transformado para, ento, ser apresentado no console de sada.

    A implementao da funo, mais abaixo no cdigo da Listagem 7, apresenta exatamente a

    impresso dos dados de um contato telefnico, e na funo main() podemos observar a

    utilizao deste operador em sua verso modificada (sobrecarregada).

    Listagem 1. Classe que representa os produtos.

    package br.com.ainosoft.jm.domain;

    /**

    * Esta classe de objetos representa um produto.

    *

    * @author pedrobrigatto

    */

    public class Produto {

    private long id;

    private String nome;

    private String descricao;

    private String qrCode;

    private String barCode;

    private float valorUnitario;

    public Produto(long id, String nome, String descricao, String qrCode,

    String barCode, float valorUnitario) {

    super();

    this.id = id;

    this.nome = nome;

    this.descricao = descricao;

    this.qrCode = qrCode;

    this.barCode = barCode;

    this.valorUnitario = valorUnitario;

    }

    // mtodos pblicos de acesso...

  • 13/3/2014 DevMedia - Verso para impresso

    http://www.devmedia.com.br/websys.5/webreader_print.asp?cat=6&artigo=4781&revista=impressao_106#a-4781 6/17

    }

    Listagem 2. Definio do modelo genrico de acesso a dados.

    package br.com.ainosoft.jm.services.dao;

    import java.util.List;

    import android.content.Context;

    import android.database.sqlite.SQLiteDatabase;

    import br.com.ainosoft.jm.services.utils.Constants;

    /**

    * Esta classe define o comportamento padro que todo objeto de acesso a dados

    * deve ter. Para tanto, utiliza-se de uma tcnica de polimorfismo denominada

    * coero ou casting.

    *

    * @author pedrobrigatto

    */

    public abstract class GenericDAO {

    protected Context context;

    protected SQLiteDatabase db;

    protected DbHelper dbHelper;

    public GenericDAO (Context context) {

    this.context = context;

    this.dbHelper = new DbHelper(context, Constants.DATABASE,

    null,Constants.DATABASE_VERSION);

    this.db = dbHelper.getWritableDatabase();

    }

    // Padro comportamental para todo objeto de acesso a dados

    public abstract boolean salvar (Object registro);

    public abstract boolean atualizar (Object registro);

    public abstract boolean excluir (Object registro);

    public abstract List listar (String ... criterios);

    public abstract List listarTodos();

    }

    Listagem 3. Implementao do modelo de acesso a dados de produtos.

    package br.com.ainosoft.jm.services.dao;

    import java.util.List;

    import android.content.ContentValues;

    import android.content.Context;

    import br.com.ainosoft.jm.domain.Produto;

    /**

    * Esta classe de objetos contm a implementao do acesso tabela de

    * produtos no banco de dados local do dispositivo. Para tanto, estende

    * um padro comportamental definido em uma classe abstrata, dando corpo

    * a todas as atividades estipuladas no mesmo.

    *

  • 13/3/2014 DevMedia - Verso para impresso

    http://www.devmedia.com.br/websys.5/webreader_print.asp?cat=6&artigo=4781&revista=impressao_106#a-4781 7/17

    * @author pedrobrigatto

    */

    public class DaoProduto extends GenericDAO {

    public static final String TABELA_PRODUTOS = "produtos";

    public DaoProduto(Context context) {

    super(context);

    }

    @Override

    public boolean salvar(Object registro) {

    if (registro instanceof Produto) {

    Produto produto = (Produto) registro;

    ContentValues values = new ContentValues();

    values.put("id", produto.getId());

    values.put("nome", produto.getNome());

    values.put("descricao", produto.getDescricao());

    values.put("barcode", produto.getBarCode());

    values.put("qrcode", produto.getQrCode());

    values.put("valor", produto.getValorUnitario());

    if (db.insert(TABELA_PRODUTOS, null, values) > 0) {

    return true;

    }

    }

    return false;

    }

    @Override

    public boolean atualizar(Object registro) {

    return false;

    }

    @Override

    public boolean excluir(Object registro) {

    return false;

    }

    @Override

    public List listar(String... criterios) {

    return null;

    }

    @Override

    public List listarTodos() {

    return null;

    }

    }

    Listagem 4. Exemplo de polimorfismo por coero na API do Android.

    package br.com.ainosoft.jm;

  • 13/3/2014 DevMedia - Verso para impresso

    http://www.devmedia.com.br/websys.5/webreader_print.asp?cat=6&artigo=4781&revista=impressao_106#a-4781 8/17

    import android.app.Activity;

    import android.content.Context;

    import android.os.Bundle;

    import android.view.LayoutInflater;

    import android.view.View;

    //Exemplo da recuperao de uma view a partir do servio LayoutInflater

    public class JavaMagazinePolimorfismoActivity extends Activity {

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    LayoutInflater inflater = (LayoutInflater)

    getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    View mainView = inflater.inflate(R.layout.main, null);

    setContentView(mainView);

    }

    }

    Listagem 5. Exemplo de sobrecarga de mtodos na API do Android.

    package br.com.ainosoft.jm;

    import android.app.Activity;

    import android.os.Bundle;

    //Primeiro exemplo de sobrecarga: parmetro fornecido um inteiro

    public class JavaMagazinePolimorfismoActivity extends Activity {

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    }

    }

    //---------------------------------------------------------------

    package br.com.ainosoft.jm;

    import android.app.Activity;

    import android.os.Bundle;

    import android.view.View;

    //Segundo exemplo de sobrecarga: parmetro fornecido um objeto View

    public class JavaMagazinePolimorfismoActivity extends Activity {

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    View content = new View(this);

    // Monta-se o objeto View que deve ser carregado na atividade.

    setContentView(content);

  • 13/3/2014 DevMedia - Verso para impresso

    http://www.devmedia.com.br/websys.5/webreader_print.asp?cat=6&artigo=4781&revista=impressao_106#a-4781 9/17

    }

    }

    Listagem 6. Exemplo de sobrecarga de operadores (uso).

    package br.com.ainosoft.jm;

    import android.app.Activity;

    import android.os.Bundle;

    import android.util.Log;

    public class JavaMagazinePolimorfismoActivity extends Activity {

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    Log.i("[JavaMagazine]", "Este um exemplo de" +

    "sobrecarga do operador de soma muito" +

    "utilizado em Java");

    }

    }

    Listagem 7. Exemplo de sobrecarga de operadores - C++ (criao).

    #include

    using std::cout;

    using std::cin;

    using std:endl;

    using std::ostream;

    using std:istream;

    #include

    using std::setw;

    class PhoneNumber {

    // Cabealho da funo de sobrecarga do operador de insero em

    // uma stream de sada (funo no membro)

    friend ostream &operator

  • 13/3/2014 DevMedia - Verso para impresso

    http://www.devmedia.com.br/websys.5/webreader_print.asp?cat=6&artigo=4781&revista=impressao_106#a-4781 10/17

    output

  • 13/3/2014 DevMedia - Verso para impresso

    http://www.devmedia.com.br/websys.5/webreader_print.asp?cat=6&artigo=4781&revista=impressao_106#a-4781 11/17

    *

    * @author pedrobrigatto

    */

    public abstract class GenericDaoParam {

    protected Context context;

    protected SQLiteDatabase db;

    protected DbHelper dbHelper;

    public GenericDaoParam (Context context) {

    this.context = context;

    this.dbHelper = new DbHelper(context, Constants.DATABASE,

    null, Constants.DATABASE_VERSION);

    this.db = dbHelper.getWritableDatabase();

    }

    // Contrato que deve ser seguido por objetos de acesso a dados

    public abstract boolean salvar (T registro);

    public abstract boolean atualizar (T registro);

    public abstract boolean excluir (T registro);

    public abstract List listar (String ... criterios);

    public abstract List listarTodos();

    }

    Listagem 9. Implementao do acesso a dados de produtos por parametrizao.

    package br.com.ainosoft.jm.services.dao;

    import java.util.List;

    import android.content.ContentValues;

    import android.content.Context;

    import br.com.ainosoft.jm.domain.Produto;

    public class DaoProdutoParam extends GenericDaoParam {

    public static final String TABELA_PRODUTOS = "produtos";

    public DaoProdutoParam(Context context) {

    super(context);

    }

    @Override

    public boolean salvar(Produto registro) {

    ContentValues values = new ContentValues();

    values.put("id", registro.getId());

    values.put("nome", registro.getNome());

    values.put("descricao", registro.getDescricao());

    values.put("barcode", registro.getBarCode());

    values.put("qrcode", registro.getQrCode());

    values.put("valor", registro.getValorUnitario());

    if (db.insert(TABELA_PRODUTOS, null, values) > 0) {

    return true;

    }

    return false;

  • 13/3/2014 DevMedia - Verso para impresso

    http://www.devmedia.com.br/websys.5/webreader_print.asp?cat=6&artigo=4781&revista=impressao_106#a-4781 12/17

    }

    @Override

    public boolean atualizar(Produto registro) {

    return false;

    }

    @Override

    public boolean excluir(Produto registro) {

    return false;

    }

    @Override

    public List listar(String... criterios) {

    return null;

    }

    @Override

    public List listarTodos() {

    return null;

    }

    }

    Pelo cdigo possvel perceber que utilizamos um parmetro genrico, de nome T.

    Toda a definio do padro comportamental da classe GenericDaoParam ter sua base em

    funo deste tipo. E por que T? Na documentao do recurso de Generics em Java,

    apresentada uma conveno para definio dos tipos de parmetros. A Tabela 2 mostra um

    resumo dos tipos utilizados, com uma breve descrio a respeito deles.

    [abrir imagem em janela]

    Tabela 2. Conveno para tipos de parmetros.

    J na implementao do contrato definido na classe GenericDaoParam para a manipulao

    de produtos, atravs da classe intitulada DaoProdutoParam, o tipo genrico T substitudo

    pelo tipo concreto Produto, o mesmo utilizado no exemplo de polimorfismo por coero.

    Quando isso feito, todos os mtodos que foram definidos a partir deste tipo genrico so

    automaticamente redefinidos para trabalhar com o tipo concreto utilizado. Ou seja: em um

    primeiro momento, na definio de um contrato genrico, trabalhamos com um parmetro

    igualmente genrico, que substitudo por um tipo concreto quando o contrato

    implementado.

    Polimorfismo por incluso

    Vamos ltima tcnica de polimorfismo, a segunda das tcnicas consideradas universais. O

  • 13/3/2014 DevMedia - Verso para impresso

    http://www.devmedia.com.br/websys.5/webreader_print.asp?cat=6&artigo=4781&revista=impressao_106#a-4781 13/17

    nome desta tcnica Incluso, e comearemos da mesma maneira que vimos todas as outras:

    um exemplo prtico de uso. Analise a Listagem 10, que nos traz um exemplo de implementao

    usando o recurso de incluso. J a Listagem 11 traz um exemplo de uso de incluso dentro da

    prpria API do Android. Mas voltemos, neste instante, Listagem 10.

    Pelo cdigo da atividade intitulada JavaMagazinePolimorfismoActivity, podemos perceber a

    declarao de um atributo chamado dao, de um tipo genrico GenericDAO. Esta uma classe

    que j analisamos neste artigo, que se utiliza da tcnica de polimorfismo por coero para

    representar genericamente objetos de acesso a dados em bancos de dados.

    Entretanto, sabemos que no podemos criar instncias de tipos abstratos, sejam estes

    classes abstratas ou interfaces.

    Portanto, em tempo de execuo, tudo o que temos so sempre objetos. Ainda na classe

    JavaMagazinePolimorfismoActivity, verificamos que o objeto criado do tipo DaoProduto, e a

    varivel dao quem fica responsvel por guardar a referncia para o objeto. Permite-se, na

    hierarquia estabelecida entre as classes GenericDAO e DaoProduto, que um objeto de acesso

    a dados de produtos seja tratado como um objeto de acesso a dados genrico, pelo conceito

    de generalizao/especializao do paradigma orientado a objetos. Isto quer dizer, em outras

    palavras, que esto includos na definio de um objeto genrico de acesso a dados

    (representados pela classe GenericDAO) qualquer tipo especialista desta classe, que o caso

    de DaoProduto. E disso que o polimorfismo por incluso trata.

    Esta tcnica de polimorfismo usada intensamente em inmeros frameworks conhecidos no

    mercado. Praticamente toda biblioteca baseia-se em interfaces, que expem padres de

    comportamento e constantes conhecidas por ela e que devem ser seguidos por

    implementaes que desejem utilizar seus recursos e suas funcionalidades. o que podemos

    chamar de protocolos de comunicao para estabelecer contato entre camadas, mdulos e

    sistemas.

    Tomando novamente por exemplo a prpria API do Android, vamos analisar um de seus

    elementos centrais: android.content.Context. Em diferentes nveis, os componentes mais

    importantes de sua arquitetura estendem esta classe.

    A Tabela 3 descreve algumas delas, e seu papel central.

    [abrir imagem em janela]

    Tabela 3. Componentes que herdam o padro de android.content.Context.

    Portanto, pelo princpio da incluso, poderamos guardar, em uma varivel do tipo

    android.content.Context, uma referncia para objetos de qualquer um desses tipos

    apresentados na Tabela 3. Desta forma, reduzimos a quantidade de memria a ser alocada

    para cada instncia da classe que estamos desenvolvendo, uma vez que estamos

    trabalhando, atravs de uma varivel nica, com instncias de tipos diferentes em pontos

    diferentes do cdigo.

    Muitas vezes podemos observar - e incluir em nossas implementaes - a utilizao conjunta

    das tcnicas de incluso e parametrizao. Verifique, nas Listagens 12 e 13, uma situao em

  • 13/3/2014 DevMedia - Verso para impresso

    http://www.devmedia.com.br/websys.5/webreader_print.asp?cat=6&artigo=4781&revista=impressao_106#a-4781 14/17

    que isto se aplica.

    Pelo cdigo, podemos observar a definio de um template para todo objeto de acesso a

    dados, j exibido na Listagem 8 deste artigo, que utiliza parmetros genricos (do tipo T) para

    acomodar qualquer tipo de objeto desejado.

    J na especializao deste template para o caso particular de produtos, verificamos a criao

    de uma instncia que representa a lista de produtos a ser alimentada e, em seguida,

    retornada.

    Listagem 10. Exemplo de polimorfismo por incluso.

    package br.com.ainosoft.jm;

    import android.app.Activity;

    import android.os.Bundle;

    import br.com.ainosoft.jm.domain.Produto;

    import br.com.ainosoft.jm.services.dao.DaoProduto;

    import br.com.ainosoft.jm.services.dao.GenericDAO;

    public class JavaMagazinePolimorfismoActivity extends Activity {

    private GenericDAO dao;

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    Produto produto = new Produto("Produto ABC");

    produto.setQrCode("ECL109212");

    produto.setDescricao("Produto fictcio");

    produto.setValorUnitario(10.53f);

    dao = new DaoProduto(this);

    dao.salvar(produto);

    }

    }

    Listagem 11. Exemplo de polimorfismo por incluso na biblioteca do Android.

    package br.com.ainosoft.jm;

    import android.app.Activity;

    import android.content.Context;

    import android.os.Bundle;

    import android.util.Log;

    import br.com.ainosoft.jm.services.JMService;

    public class JavaMagazinePolimorfismoActivity extends Activity {

    private Context context;

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

  • 13/3/2014 DevMedia - Verso para impresso

    http://www.devmedia.com.br/websys.5/webreader_print.asp?cat=6&artigo=4781&revista=impressao_106#a-4781 15/17

    setContentView(R.layout.main);

    Log.i("[JavaMagazine]", "Este um exemplo de" +

    "sobrecarga do operador de soma muito" +

    "utilizado em Java");

    // Verifique que estamos usando uma varivel tipada como

    // android.content.Context para guardar uma referncia para uma

    // instncia da aplicao (android.app.Application)

    context = getApplication();

    // Verifique, agora, que estamos usando a mesma varivel tipada

    // como android.content.Context para guardar uma referncia para

    // uma instncia de um servio (android.app.Service)

    context = new JMService();

    }

    }

    Listagem 12. Exemplo mesclando as tcnicas de incluso e parametrizao.

    package br.com.ainosoft.jm.services.dao;

    import java.util.List;

    import android.content.Context;

    import android.database.sqlite.SQLiteDatabase;

    import br.com.ainosoft.jm.services.utils.Constants;

    /**

    * Classe de objetos que manipulam informaes em banco de dados.

    * Esta classe emprega a tcnica denominada parametrizao, que em Java se

    * manifesta de forma bem direta no conceito conhecido como Generics.

    *

    * @author pedrobrigatto

    */

    public abstract class GenericDaoParam {

    protected Context context;

    protected SQLiteDatabase db;

    protected DbHelper dbHelper;

    public GenericDaoParam (Context context) {

    this.context = context;

    this.dbHelper = new DbHelper(context,Constants.DATABASE,

    null,Constants.DATABASE_VERSION);

    this.db = dbHelper.getWritableDatabase();

    }

    public abstract boolean salvar (T registro);

    public abstract boolean atualizar (T registro);

    public abstract boolean excluir (T registro);

    public abstract List listar (String ... criterios);

    public abstract List listarTodos();

    }

    Listagem 13. Exemplo mesclando as tcnicas de incluso e parametrizao.

  • 13/3/2014 DevMedia - Verso para impresso

    http://www.devmedia.com.br/websys.5/webreader_print.asp?cat=6&artigo=4781&revista=impressao_106#a-4781 16/17

    package br.com.ainosoft.jm.services.dao;

    import java.util.ArrayList;

    import java.util.List;

    import android.content.Context;

    import br.com.ainosoft.jm.domain.Produto;

    public class DaoProdutoParam extends GenericDaoParam {

    public static final String TABELA_PRODUTOS = "produtos";

    public DaoProdutoParam(Context context) {

    super(context);

    }

    @Override

    public boolean salvar(Produto registro) {

    return false;

    }

    @Override

    public boolean atualizar(Produto registro) {

    return false;

    }

    @Override

    public boolean excluir(Produto registro) {

    return false;

    }

    @Override

    public List listar(String... criterios) {

    return null;

    }

    @Override

    public List listarTodos() {

    List produtos = new ArrayList();

    // recupera-se os produtos do banco de dados

    return produtos;

    }

    }

    Pelo cdigo, podemos observar o uso alternado dos tipos genrico e especialista, bem como

    o uso de parametrizao e posterior substituio do parmetro pelo tipo especfico (Produto).

    Isto permite uma flexibilidade muito grande dentro de projetos orientados a objetos, uma

    legibilidade visivelmente maior e, consequentemente, uma manutenibilidade extremamente

    facilitada.

    Concluses Chegamos ao final deste artigo. Ao longo de todo o texto, pudemos verificar todos os tipos

  • 13/3/2014 DevMedia - Verso para impresso

    http://www.devmedia.com.br/websys.5/webreader_print.asp?cat=6&artigo=4781&revista=impressao_106#a-4781 17/17

    existentes de polimorfismo, bem como exemplos de aplicao de cada um deles.

    imprescindvel, para todo bom desenvolvedor de software, ter este conceito muito bem

    compreendido (bem como todos os outros relacionados ao paradigma de desenvolvimento

    orientado a objetos), pois isto permitir uma absoro muito mais rpida de muitos frameworks

    existentes no mercado, que aplicam fortemente tcnicas como coero, parametrizao e

    incluso.

    Um sistema que utiliza corretamente tcnicas polimrficas ser sempre um sistema mais

    legvel, padronizado, escalvel e flexvel, tornando sua manuteno e evoluo facilitadas.

    Pedro E. Cunha Brigatto

    Engenheiro da Computao graduado pela Universidade Federal de So Carlos, desenvolvedor

    certificado SAP Netweaver (Java Stack) e possui a certificao SCJP. Especialista em Engenharia de

    Software graduado pela Unimep e ps-graduado em Administrao pela Fundao BI-FGV, atua com

    desenvolvimento de software desde 2005. Atualmente desempenha o papel de arquiteto de software

    na Ci&T apoiando projetos plataformas como SUP, Afaria, Android e BlackBerry, sendo tambm

    proprietrio da empresa ainosoft e professor universitrio nas Faculdades Integradas Einstein, na

    cidade de Limeira.