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!


segunda-feira, 17 de fevereiro de 2014

Java, C# : Imutabilidade

Fala galera, tudo tranquilo?

Você já teve interesse de conhecer como são as implementações de Listas ? (List do C#, Java)

Basicamente, as interfaces(List) definem os tipos de operações que podem ser realizadas nas Lista. Vou escrever algo bem bacana, faremos uma implementação de Lista Imutável.

Imutabilidade
Basicamente, é uma característica de um objeto permanecer o mesmo sempre. Quer saber mais sobre Imutabilidade: Bruno Nardini http://www.brunonardini.com.br/artigos/favoreca-a-imutabilidade-e-a-simplicidade

A classe String, tanto do Java quanto C# , encapsula alguns métodos de manipulação de String, como o toUpperCase() (C# = ToUpper()), que têm o objetivo de converter sua string para maiúsculo. Porém por baixo dos panos, o que acontece é você receberá uma nova instância, com o conteúdo de sua string antiga convertida para maiúsculo. (Você pode verificar isso nos links acima)

Já definido o que é Imutabilidade, vamos ao conceito básico de Listas Ligadas (Linked List). (http://www.caelum.com.br/apostila-java-estrutura-dados/listas-ligadas/#5-1-solucao-classica-de-lista-ligada)

Uma Lista Ligada é uma lista onde o elemento atual "aponta"(tem o endereço) para/do o seu próximo irmão, analisem a fotografia abaixo:



Um conceito simples, agora vamos a prática, assim podemos misturar os dois conceitos! (Imutabilidade e Linked List). No exemplo vai rolar um pouco Generics, se já sabe legal, caso não: http://en.wikipedia.org/wiki/Generic_programming#Generics_in_Java .

Primeiro, vamos criar uma interface para nossas listas, para isso, crie um projeto novo no Eclipse, dê um nome e vamos lá:

New -> Interface

public interface List {
    T cabeca();
    List cauda();
    List adicionaNoComeco(T elemento);
    T pegaPosicao(int position);
    List removePrimeiraPosicao();
}

Bom e o que é cabeça e cauda?
Cabeça é o elemento superior de nossa lista, ou seja a head da Lista.
Cauda é todo o restante da lista, é composta por sua cabeça e outra cauda, e assim respectivamente.

Nosso método adicionaNoComeco(T elemento) recebe um parâmetro e retorna uma nova Lista com o respectivo elemento adicionado. Bem parecido com o método removePrimeiraPosicao() que remove o primeiro elemento e retorna a cauda da lista.

Bom vamos as implementações, vamos criar uma nova classe, que podemos chamar de No, ou seja, serão os respectivos nós de nossa Lista:

public class No implements List {
    private final T cabeca;
    private final List cauda;

    public No(T cabeca, List cauda) {
        this.cabeca = cabeca;
        this.cauda = cauda;
    }
    @Override
    public T cabeca() {
        return cabeca;
    }
    @Override
    public List cauda() {
        return cauda;
    }
    @Override
    public List adicionaNoComeco(T elemento) {
        return new No(elemento, this);
    }
    @Override
    public T pegaPosicao(int position) {
        if (position == 0)
            return cabeca();

        return cauda.pegaPosicao(position - 1);
     }
    @Override
    public List removePrimeiraPosicao() {
    return cauda();
    }
}

Entenda:
Ao criar um No, nós receberemos a cabeça (elemento) e sua respectiva cauda (List). Fora o método pegaPosicao, o restante é bem trivial, por isso não entrarei em maiores detalhes.

pegaPosicao(T elemento)
Esse método faz uso recursivo de si próprio, ou seja, ele percorre a cauda, caso o posicao não seja 0, e recursivamente ele vai caminhando de cabeça em cabeça, das caudas, para encontrar o elemento desejado. Bem simples e objetivo.

Certo, feito isso, fica simples entender algumas coisas, a primeira de todas, como será o fim de nossa lista?
Temos que saber onde a Lista tem seu final e como o fazemos?

Faremos outra implementação de List, que agora chamaremos de Nil, será o fim de nossa lista.

public class Nil implements List {
    @Override
    public T cabeca() {
        throw new RuntimeException("Lista Vazia");
    }
    @Override
    public List cauda() {
        throw new RuntimeException("Lista Vazia");
    }
    @Override
    public List adicionaNoComeco(T elemento) {
        return new No(elemento, this);
    }
    @Override
    public T pegaPosicao(int position) {
        throw new RuntimeException("A lista não possui elementos");
    }
    @Override
    public List removePrimeiraPosicao() {
        throw new RuntimeException(
        "Impossível remover elementos de uma lista vazia");
    }
}

O Nil, que como dito acima, tem o objetivo de ser o fim da lista, a única coisa que podemos escrever interessante ao seu respeito é que a reescrita do método adicionaNoComeco vai retornar uma nova instância de No, ou seja, iniciaremos uma lista.

Feito isso, temos um Container, o List, que armazena valores e possui funções para alterar os dados internos, isso nos ajuda muito com a Imutabilidade, nos sentimos mais seguros e sabemos que nosso objeto não será um mutante, que pode perder/alterar seus valores em tempo de execução.

Bom galera, o conceito de hoje foi bem bacana e construtivo, é o que tenho mais feito no meu treinamento com o Jonas, aqui na Lambda3. Espero que tenha ficado claro.

Para os C# manjadores, no meu Github tem um exemplo parecido escrito em C#. Para os Javas, deixarei outro repositório no GitHub já com os testes implementados.

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

Valeu galera!

quinta-feira, 13 de fevereiro de 2014

C#: Um Pouco Mais Recursivo

E aí galera, tudo beleza?

Hoje o assunto é semelhante ao meu post a respeito de Recursividade (http://aterribili.blogspot.com.br/2014/01/haskell-recursividade.html), vou falar mais um pouco, só que ao invés de usarmos Haskell, vamos usar C#!

(Se por acaso você não possua uma forma de compilar C#, replique o exercício em Java, é bem parecido!)

Se você ainda não sabe o que é Recursividade, aconselho ler meu post anterior.

Vamos imaginar um problema simples e que você não possa usar um for para resolver?

Crie um método que Multiplica uma String, ou seja:
"a" * 3 = "aaa"
"ab" * 2 = "abab"

Consegue imaginar algo do tipo?

Com o uso da Resursividade, podemos resolver esse problema de forma simples e elegante.

Vamos ver o Teste de Unidade primeiro, assim fica mais simples de entender:

...
[TestMethod]
public void DeveMultiplicarString(){
  Assert.AreEqual("abab", new Multiplicador().MultiplicaString(2, "ab");
}

Daí ficou simples entender o que deve acontecer.

Vamos criar a classe Multiplicador:

public class Multiplicador() {
  public String MultiplicaString(int vezes, String string){
    if(vezes == 1) //Aqui definimos uma Guarda
      return string;

    return string + Multiplicador(--vezes, string); 
  }
}

Feito isso, entenda que a Guarda é um ponto onde a execução do método será parada.
A execução do método é efetuada de forma recursiva, toda vez que a variável vezes for maior que 1.
E existem n exemplos onde recursão é aplicável e criamos uma função muito mais legível aos olhos de outro programador.

Bom galera, por hoje é só! Estou preparando um post a respeito de Funcs no C#.

Qualquer coisa, email-me: abner.terribili@lambda3.com.br ou comente abaixo!

Cheers!


segunda-feira, 10 de fevereiro de 2014

Java: Testes de Unidade

E aí galera, tudo tranquilo?

Passei um tempo fora daqui, porque estou em processo de treinamento com o Jonas Abreu, na Lambda3. Minha semana, ausente do blog, começou muito diferente. Meu primeiro estágio na área foi em uma empresa convencional, então estava acostumado com aquele lance de calça jeans, tênis e Gerentes com caras de bravos.
Então conheci a Lambda3, através de um amigo, e fiquei super interessado na filosofia e nos valores, que são bem próximos aos meus. Os apaixonados por desenvolvimento, que não curtem gerentes e nem trabalhar vestido como se fosse a um casamento. No primeiro dia, foi um choque, realmente não é normal ver um dos Fundadores (Giovanni Bassi) de Chinelo! Mas venho concluindo que isso só nos deixa mais confortáveis para maiores desafios!

Continuarei me dedicando a vocês e já conversei com o Jonas, vou escrever toda segunda-feira a minha experiência da semana.

Para começar de um jeito novo, minha primeira lição foi TDD!
Imagine o quão confortável é refatorar todo seu código e ter certeza de que se rolar alguma merda, você vai saber antes da Produção. :)

E o assunto será exatamente esse: TDD! (Test Driven Development)

O que é TDD?
Desenvolvimento Orientado a Testes. Você simplesmente escreve seus testes antes de codar seu software. Existe algo mais profundo aqui: http://pt.wikipedia.org/wiki/Test_Driven_Development

O que é um Teste?
Imagine a seguinte situação: Você precisa verificar se dois números foram somados corretamente (Exemplo extremamente didático). Assim você escreve seu teste e vai codar de forma que aquele teste seja satisfeito. Vamos fazer um exemplo prático (Java):

Crie um novo projeto TestandoTDD no Eclipse;

No diretório raiz de TestandoTDD crie um source folder test;

Feito isso, crie dentro do folder test um novo arquivo JUnit Test Case, caso role de você não encontrar o JUnit no seu Eclipse: http://www.vogella.com/tutorials/JUnit/article.html

Por convenção, não sei de quem, nós damos o nome do teste assim: SuaClasseTest
Ou seja, SomaTest.

Bom, agora o lindo e maravilhoso código:

// Não se esqueça dos imports
public class SomaTest{
  @Test
  public void DeveSomarDoisNumeros(){
    // Setup
    Soma soma = new Soma(1, 2);

    // Execução e Verifição
    Assert.assertEquals(4, soma.ExecutaSoma());
  }
}

Bom, mas e aí o que tudo isso significa?
O nome do método de teste tem que ser bem objetivo, muito mesmo. Assim caso der erro, fica "simples" de identificar o ocorrido.

Assim que você escrever a annotation @Test, você declara que aquele é um metodo para testar um caso. (Mais Detalhes: http://junit.sourceforge.net/javadoc/org/junit/Test.html)

O teste é convencional é composto de 3 etapas: Setup, Execução e Verificação.

No Setup, nós definimos o que será testado, no nosso caso o Objeto Soma(que ainda não existe).

Nossa execução acontece no método soma.ExecutaSoma(), que deve retornar o resultado da soma.

E o mais legal aí é a Verificação, que no momento acontece com a Classe Assert (http://junit.sourceforge.net/javadoc/org/junit/Assert.html). Essa classe é composta de diversos métodos que avaliam diversas situações, nós usaremos o assertEquals(int Esperado, int Resultado) que compara dois números.

Caso nosso retorno seja o resultado esperado (3), veremos a aba do JUnit (geralmente a esquerda) com uma barra verde. Caso contrário a cor vermelha predomina.

Bom, nosso teste está escrito, como provavelmente você sabe, ele não funcionará, pois não temos a classe Soma e nem mesmo o seu respectivo método.

Vamos na pasta /src e e criarmos a classe Soma.java. Nosso objetivo atual é satisfazer o teste, ou seja, implementar a classe soma, de forma que nosso teste dê certo.

File -> New -> Class

Soma.java:

//imports
public class Soma {
  private int x;
  private int y;

  public Soma(int x, int y){
    this.x = x;
    this.y = y;
  }

  public int ExecutaSoma(){
    return x + y;
  }
}

E pronto, temos uma situação que satisfaz nosso teste!

Teste seu SomaTest clicando com o direito em cima do arquivo e Run as -> JUnit Test.

Isso foi um simples Teste de Unidade, onde testamos a função ExecutaSoma() da classe Soma.

Na Aba JUnit, logo abaixo você verá algo como Failure Trace, onde caso ocorra algum erro no teste, serão impressos os resultados. Como você deve ter visto, nosso teste retornou um erro, procure no Failure Trace qual foi o erro. E esse é o exercício de hoje, e a dica é você pode encontrar algo no expected:<valor> but was:<valor>. Ou seja valor experado e valor atual.

Caso você tenha ficado com preguiça de digitar todo esse código, que não é muito. Ele está lá no meu Github, é só baixar, importar no Eclipse e testar!

Qualquer dúvida, observação ou mesmo dica email-me: abner.terribili@lambda3.com.br ou comente abaixo!


sábado, 1 de fevereiro de 2014

Haskell: Lazy Evaluation e Listas

E aí galera!

Continuando na saga Haskell, hoje vou falar a respeito de uma de suas maiores características: Lazy Evaluation. (Avaliação Preguiçosa)



O que é Lazy Evaluation?
É uma estratégia utilizada para avaliação de funções. Ela consiste em não avaliar nenhuma subexpressão ou função até que seu retorno seja conhecido como necessário, ou seja, no momento em que o valor, da expressão ou função, for requisitado para continuidade da função, ele será calculado.

Quais são as vantagens?
- Melhor desempenho ao evitar cálculos desnecessários, evitando condições de erro na avaliação de expressões compostas.
- Habilitade de representar potencialmente estruturas de dados infinitas, exemplo:
Você precisa fazer a soma de a partir de n até o infinito:

-- A função lista, recebe um inteiro e retorna uma lista de inteiros dados a partir de n

lista :: Int -> [Int]
lista = n : lista (n + 1)

Ou seja, a função lista gera infinitos números para uma lista de inteiros a partir de um número passado como parâmetro. Vamos executar esse código:
Main> lista 5
lista 5 = 5 : lista (5 + 1)
        = 5 : 6 : lista (6 + 1)
        = 5 : 6 : 7 : lista (7 + 1)
        ...
        ....
        .....
        ......

A soma só é executada quando necessária :).

Para maior compreensão do exemplo que citei, vou deixar algumas noções sobre Listas em Haskell.

Listas
Uma lista é uma estrutura de dados que representa uma coleção de objetos homogêneos. Ou seja, objetos que são do mesmo Tipo de Dado.

Listas em Haskell
Uma lista em Haskell é composta por head (cabeça) e tail (corpo). A cabeça é o primeiro objeto da lista, por onde é feito o nó de acesso da lista. A partir dela(head) temos acesso aos objetos que estão no tail da lista.

Para criar uma lista em Haskell é bem simples:
-- Lista de números
fibonacci :: [Int]
fibonacci = [1, 1, 2, 3, 5, 8]
-- Lista de Char
nome :: [Char]
nome = ['A', 'B', 'C', 'D']
-- Lista de String
lista_char :: [[Char]]
lista_char = ["Haskell", ['H', 'A', 'S', 'K', 'E', 'L', 'L']]
-- A string "Haskell" é uma lista de Char

Legal né?

Para criar uma lista vazia:
[]


Pronto, alguns exercícios serão os melhores exemplos.
Vá ao seu terminal e entre no interpretador Hugs.

Digite:

Main> 1 : []

[1]


Main> 1 : 2 : 3 : []

[1,2,3]


Acho que deu pra perceber o que estamos fazendo né? Adicionando elementos a lista. Bem simples, com o caractere ':' nós adicionamos elementos a lista.

Podemos até mesmo fazer comparações de listas:
Main> [1,2,3] == (1 : 2 : 5 : [])

False


Main> [a,b] == [b, a]

ERROR - Undefined variable "b"


Por que vemos esse erro?
Simplesmente porque estamos a usar um tipo de dado Char, que DEVE vir entre ' '.

Main> ['a', 'b'] == ['b', 'a']

False


Pronto.
Não se esqueça também que os elementos de uma lista estão entre [ ] e separados por vírgula.

Galera, por hoje é só. Qualquer dúvida, comente abaixo ou email-me: abner.terribili@gmail.com.

Cheers!