Hoje vou dar continuidade ao assunto Polimorfismo e suas diversas formas, para que não leu Polimorfismo Parte 1.
E faremos algumas mutretas usando os poderes do Polimorfismo.
Imagine a situação onde você precisa categorizar 3 objetos diferentes que partilhem dos mesmos atributos, em um dos meus exercícios com o Jonas, na Lambda3, nós fizemos, com fins educacionais, um mini avaliador de endereços web, que retorna os corretos endereços.
Basicamente, vamos criar um novo projeto Java no Eclipse. Vamos manter o costume e escrever um teste básico:
@Test
public void deveRetornarDominioBuscape(){
ProcessadorUrl processador = new ProcessadorUrl("buscape");
Assert.assertEquals("http://www.buscape.com.br", processador.dominio());
}
@Test
public void deveRetornarParametroBuscape(){
ProcessadorUrl processador = new ProcessadorUrl("buscape");
Assert.assertEquals("p", processador.parametro());
}
@Test
public void deveRetornarCookie(){
ProcessadorUrl processador = new ProcessadorUrl("buscape");
Assert.assertEquals("bp", processador.cookie());
}
Definido nosso teste, podemos criar uma classe para satisfazer o teste:
public class ProcessadorUrl {
private String dominio;
public Dominio(String dominio){
this.dominio = dominio;
}
public String dominio(){
if(dominio=="buscape")
return "http://www.buscape.com.br";
if(dominio=="bondfaro")
return "http://www.bondfaro.com.br";
return "";
}
public String parametro(){
if(dominio=="buscape")
return "p";
if(dominio=="bondfaro")
return "b";
return "";
}
public String cookie(){
if(dominio=="buscape")
return "bp";
if(dominio=="bondfaro")
return "bf";
return "";
}
}
Pronto, conseguimos satisfazer nosso teste, mas espera aí, se o tema é Polimorfismo, por que estamos fazendo nessa forma procedimental?
Consegue ver que nossa classe ProcessadorUrl possui muitas responsabilidades? Ela é obrigada a avaliar o dominio, parametro e o cookie? Acho que para nossos "sites" temos características semelhantes, para todos os sites devemos ter metodos que busquem o domínio, parâmetro e cookie, certo? Então vamos para a Orientação a Objetos.
E como fazer bom uso do polimorfismo nesse caso? Antes de prosseguir, rode seus testes. Crie mais alguns para o bondfaro. Divida as responsabilidades, nossa classe ProcessadorUrl, deve apenas reconhecer o parâmetro String de dominio, e retornar o objeto correto. Creio ser uma boa forma de início.
ProcessadorUrl = deveria apenas avaliar dominio
Buscape = ter os atributos dominio, parametro e cookie
Bondfaro = igual Buscape
Vamos refatorar nossas classes:
De início vamos montar nossa classe ProcessadorUrl:
public class ProcessadorUrl{
private String dominio;
public Dominio(String dominio){
this.dominio = dominio;
}
Site avaliaDominio(){
if(dominio=="buscape")
return new Buscape();
if(dominio=="bondfaro")
return new Bondfaro();
throw new RuntimeException("Não foram encontrados registros");
}
}
Já evitamos aquele retorno horrível de String vazia, dividimos mais a responsabilidade da nossa Classe ProcessadorUrl, agora vamos aos nossos "Sites". Podemos notar comportamentos semelhantes, como dito acima, sabendo disso que tal criar uma interface que delega as responsabilidades que os objetos devam implementar.
Crie uma Interface Site, onde teremos os seguintes métodos:
public interface Site(){
String Dominio();
String Parametro();
String Cookie();
}
Para completar podemos criar a classe Buscape, que implementará a interface Site:
public class Buscape implements Site {
@Override
public String dominio() {
return "http://www.buscape.com.br";
}
@Override
public String parametro() {
return "p";
}
@Override
public String cookie() {
return "bp";
}
}
Feito isso, rode seus testes! E aí o que rolou? Um problemão (rs), devemos refatorar nosso teste, agora ele também trabalha com objetos.
@Test
public void deveRetornarDominioBuscape(){
ProcessadorUrl processador= new ProcessadorUrl("buscape");
Assert.assertEquals("http://www.buscape.com.br", processador.avaliaDominio().dominio());
}
@Test
public void deveRetornarParametroBuscape(){
ProcessadorUrl processador= new ProcessadorUrl("buscape");
Assert.assertEquals("p", processador.avaliaDominio().parametro());
}
@Test
public void deveRetornarCookie(){
ProcessadorUrl processador = new ProcessadorUrl("buscape");
Assert.assertEquals("bp", processador.avaliaDominio().cookie());
}
O retorno do objeto não é muito explícito, mas nosso processador, possui o método avaliaDominio() que retorna um objeto do tipo Site, isso mesmo, assim podemos buscar os devidos comportamentos das devidas implementações da interface Site.
Legal né? Você então, usando Polimorfismo com uso de interfaces, pode fazer com que seus objetos partilhem os mesmas responsabilidades e direfentes comportamentos, evitando assim Heranças.
Aqui terminamos mais um exemplo do bom uso do Polimorfismo. Se surgir alguma dúvida, corre lá no meu Github
E a dica de hoje é, na verdade pergunta, já sabe usar o controlador de versões Git? Caso não e esteja afim de aprender, o Jonas tem feito um bom trabalho com uma mistura de prática e jogos: Git Game
Bom, por hoje é só galera. Qualquer coisa email-meabner.terribili@lambda3.com.br ou comente abaixo.
Nenhum comentário:
Postar um comentário