segunda-feira, 24 de fevereiro de 2014

C# : Polimorfismo nas suas diversas formas (Parte 1)

Fala aí galera.
Hoje o assunto é bem objetivo, vamos falar a respeito de Polimorfismo.

O que é Polimorfismo?
A primeira vista, parece algo como "Várias Formas", na verdade não é tudo isso. Encontrei uma definição bem interessante dada pelo Ivan Ricarte, da Unicamp, onde: "Polimorfismo é o princípio pelo qual duas ou mais classes derivadas de uma mesma superclasse podem invocar métodos que têm a mesma identificação (assinatura) mas comportamentos distintos, especializados para cada classe derivada, usando para tanto uma referência a um objeto do tipo da superclasse. A decisão sobre qual o método que deve ser selecionado, de acordo com o tipo da classe derivada, é tomada em tempo de execução, através do mecanismo de ligação tardia."

Bom e aí, será que ficou claro? Talvez com um exemplo mais simples, dê para entender.

Vou escrever em C#, é bem simples de replicar em Java.
Imagine que você tenha a necessidade de fazer com que Diferentes Classes possuam comportamentos semelhantes:

Em um dos meus exercícios aqui na Lambda3, tive que construir um "processador de URL's", algo que avalia o conteúdo de uma URL e de acordo faz determinada ação.

Nosso processador, não precisa encapsular diversos métodos, pois assim estaríamos dando muita responsabilidade para apenas uma classe, então basicamente o que nosso processador fará é Armazenar uma

Armazenará uma URL e a processará.

ProcessadorUrl:
class ProcessadorUrl
{
    private readonly String endereco;

    public ProcessadorUrl(String url) { this.endereco = url;}

    public String ProcessaUrl() { return endereco; }
}

Feito isso, da pra entender um pouco o que precisamos fazer. Basicamente, agora faremos as classes avaliadoras:
Farei apenas duas, para compreensão simples.

Primeira classe avaliadora:

class AvaliadorGoogle
{
    private readonly String endereco;
    
    public AvaliadorGoogle(String endereco) { this.endereco = endereco; }
    
    public bool Avalia() { return endereco.Contains("google"); }
        
    public string Executa() {
            return endereco.Replace("google", "bing"); }
}

Segunda classe avaliadora:

class AvaliadorAsdrubal
{
    private readonly String endereco;
    
    public AvaliadorAsdrubal(String endereco) { 
       this.endereco = endereco; }
    
    public bool Avalia() { 
       return endereco.Contains("asdrubal"); }
        
    public string Executa(){ 
       return endereco.Replace("asdrubal", "outro"); }
}

Agora nosso processador de URL pode fazer as comparações e retornar o necessário:

class ProcessadorUrl
{
    private readonly String endereco;
        
    public ProcessadorUrl(String url) { this.endereco = url; }
        
    public String ProcessaUrl()
    {
        if(new AvaliadorGoogle(endereco).Avalia())
               return new AvaliadorGoogle(endereco).Executa(); 
        if(new AvaliadorAsdrubal(endereco).Avalia())
               return new AvaliadorAsdrubal(endereco).Executa();
        return "";
    }
}

Então podemos notar que ambas classes, AvaliadorGoogle e AvaliadorAsdrubal, possuem comportamentos semelhantes, por que não fazer uso do Polimorfismo?

Crie uma nova Interface e de o nome de Avaliacao:

interface Avaliacao {
    bool Avalia();
    String Executa();
}

Agora os nossos Avaliadores implementarão essa interface:

class AvaliadorAsdrubal : Avaliacao
{
    private readonly String endereco;

    public AvaliadorAsdrubal(String endereco) { 
       this.endereco = endereco; }

    public bool Avalia() { 
       return endereco.Contains("asdrubal"); }
    
    public string Executa() { 
       return endereco.Replace("asdrubal", "outro"); }
}

Faça o mesmo para o avaliador Google e beleza! Vamos a classe que processa, podemos fazer bom uso do Polimorfismo:

public class ProcessadorUrl
  {
        private readonly String endereco;
        
        public ProcessadorUrl(String url)
        {
            this.endereco = url;
        }
        
        public String ProcessaUrl()
        {
           List<Avaliacao> lista = new List<Avaliacao>();
           lista.Add(new AvaliadorGoogle(endereco));
           lista.Add(new AvaliadorAsdrubal(endereco));
         
           for (var i = 0; i < lista.Count; i++){
               if(lista[i].Avalia()
                  lista[i].Executa();
           }
           return "";
        }
  }

Conseguiram compreender um bom uso do polimorfismo?

Criamos uma Lista de Objetos que implementam a interface Avaliação. Essa, como diz o Jonas, é a parte gostosa da "Herança" :).

Exemplos no meu Github:
https://github.com/aterribili/Mapeando
https://github.com/aterribili/AvaliacaoEnderecosWeb

Qualquer dúvida email-me: abner.terribili@lambda3.com.br ou comente abaixo.

Valeu galera!


Nenhum comentário:

Postar um comentário