Refatoração de Código: Unificar Interfaces

Receba em primeira mão, e com prioridade, os conteúdos Android exclusivos do Blog. Você receberá um email de confirmação. Somente depois de confirma-lo é que poderei lhe enviar os conteúdos exclusivos.

Email inválido.
Blog /Android /Refatoração de Código: Unificar Interfaces

Refatoração de Código: Unificar Interfaces

Vinícius Thiengo
(1186)
Go-ahead
"Esse tem sido um dos meus mantras: foco e simplicidade. Simples pode ser mais difícil do que o complexo. Você tem que trabalhar duro para conseguir o seu pensamento limpo para torná-lo simples. Mas vale a pena no final, porque uma vez que você chegue lá, você pode mover montanhas."
Steve Jobs
Kotlin Android
Capa do livro Desenvolvedor Kotlin Android - Bibliotecas para o dia a dia
TítuloDesenvolvedor Kotlin Android - Bibliotecas para o dia a dia
CategoriasAndroid, Kotlin
AutorVinícius Thiengo
Edição
Capítulos19
Páginas1035
Acessar Livro
Treinamento Oficial
Android: Prototipagem Profissional de Aplicativos
CursoAndroid: Prototipagem Profissional de Aplicativos
CategoriaAndroid
InstrutorVinícius Thiengo
NívelTodos os níveis
Vídeo aulas186
PlataformaUdemy
Acessar Curso
Receitas Android
Capa do livro Receitas Para Desenvolvedores Android
TítuloReceitas Para Desenvolvedores Android
CategoriaDesenvolvimento Android
AutorVinícius Thiengo
Edição
Ano2017
Capítulos20
Páginas936
Acessar Livro
Código Limpo
Capa do livro Refatorando Para Programas Limpos
TítuloRefatorando Para Programas Limpos
CategoriaEngenharia de Software
AutorVinícius Thiengo
Edição
Capítulos46
Páginas599
Acessar Livro
Quer aprender a programar para Android? Acesse abaixo o curso gratuito no Blog.
Conteúdo Exclusivo
Receba em primeira mão, e com prioridade, os conteúdos Android exclusivos do Blog.
Email inválido

Opa, blz?

Nesse artigo continuamos com a série Refatoração de Código para se tornar um developer de alto desempenho, dessa vez abordando o método de refatoração Unificar Interfaces.

Já lhe adianto que se em alguma outra refatoração foi informado que ela era a menor, na verdade, essa é a menor.

Antes de prosseguir informo que no final do artigo tem os links de todos os outros métodos de refatoração já apresentados até aqui, nessa série, e que eles podem ser utilizados em qualquer linguagem que seja possível trabalhar no paradigma orientado a objetos. Alguns métodos podem ser utilizados até mesmo no paradigma procedural.

Tópicos presentes no artigo:

Motivação

Em seu código há uma hierarquia de classes onde a superclasse, apesar de ter implementado nela alguns métodos e atributos comuns as subclasses, ainda não trabalha de forma polimórfica, pois as subclasses ainda têm trechos com as próprias implementações. Trabalhar com polimorfismo é também ter a mesma interface (métodos e atributos públicos) das subclasses.

Note que interface aqui implica em métodos e atributos com tipo de acesso public e não a Interface estrutura de linguagem.

Código de exemplo

O código desse artigo é uma simples hierarquia do mundo animal. Para permitir que parte da lógica do projeto seja alterada para trabalhar com o polimorfismo, vamos aplicar o método de refatoração na superclasse a seguir:

public abstract class Animal {
public abstract void andar();

public abstract void comer();
}

 

Abaixo a classe Formiga que herda de Animal e implementa os métodos obrigatórios:

public class Formiga extends Animal {

@Override
public void andar() {
...
}

@Override
public void comer() {
...
}

public double forcaGancho(){
...
}
}

 

E ainda temos a classe Cachorro que também herda de Animal:

public class Cachorro extends Animal {
@Override
public void andar() {
...
}

@Override
public void comer() {
...
}

public void latir(){
...
}
}

 

Nosso objetivo é permitir que a classe Animal tenha uma interface comum quanto as suas subclasses para que seja possível em um array de Animal, por exemplo, realizar o processamento polimórfico das instâncias sem necessidade de identificação de tipo, independente dos métodos invocados.

Mecânica

O método de refatoração proposto aqui, como já informado: é bem simples. Temos apenas um passo a ser implementado. Pode acreditar.

Vamos buscar métodos públicos, nas subclasses, que estejam ausentes em na superclasse sendo refatorada. Na hierarquia do projeto de exemplo temos os métodos forcaGancho() que está em Formiga e latir() que está em Cachorro.

Esses métodos ausentes terão cópias nulas (ou conteúdo vazio) em nossa superclasse Animal.

Cópias nulas?

Sim, eles não terão comportamento definido, serão vazios, pois com o objetivo de ter uma interface comum e sabendo que eles não são comuns na hierarquia de classes, não devemos forçar uma implementação comum as subclasses, dessa forma apenas deixamos os métodos vazios. Caso algum deles tenha retorno, apenas retornamos o dado padrão para o tipo de retorno, por exemplo: null para String e 0 para int.

Segue nova versão de Animal, depois de realizar a cópia de forcaGancho():

public abstract class Animal {
public abstract void andar();

public abstract void comer();

public double forcaGancho(){
return( 0 );
}
}

 

Perceba que como retorno do método colocamos o valor 0, pois em nosso caso a implementação é em Java, e para tipos primitivos numéricos o 0 é o valor padrão. Lembrando que esse retorno de valor padrão, para um método que tem retorno, é equivalente a uma implementação vazia.

Note que, antes do código acima, foi informado que realizamos uma "cópia" e não uma remoção, pois a classe Formiga mantém a implementação de forcaGancho().

Esse foi o primeiro e único passo. O que devemos fazer agora é aplicar o mesmo para todos os outros métodos públicos encontrados nas subclasses e que não têm uma referência na superclasse. Logo, ainda temos que aplicar o mesmo passo de refatoração para o método latir() de Cachorro:

public abstract class Animal {
public abstract void andar();

public abstract void comer();

public double forcaGancho(){
return( 0 );
}

public void latir(){}
}

 

Como latir() não tem retorno, literalmente não precisamos fazer nada no conteúdo dele.

Dessa forma, um código cliente que utiliza uma coleção de animais poderia seguramente trabalhar com a classe Animal e chamar todos os métodos sem necessidade de identificação de tipo de classe para saber se pode ou não invocar determinado método:

...
Animal[] animais = new Animal[2];

animais[0] = new Cachorro();
animais[1] = new Formiga();

for( Animal animal : animais ){
animal.andar();
animal.comer();
animal.latir();
animal.forcaGancho();
}
...

 

Com isso finalizamos o método de refatoração proposto aqui.

Você provavelmente deve estar se perguntando: somente vamos utilizá-lo quando for necessária a aplicação de polimorfismo?

Não. Quando for necessário que uma classe tenha uma interface única em relação a outras classes (não necessariamente subclasses) é que se aplica o método de refatoração Unificar Interfaces.

Somente com classes (superclasses) conseguimos essa interface unificada?

Não. O método pode ser aplicado para Interfaces também, mas no caso de Interface a implementação por parte das classes concretas será inevitável.

Conclusão

Polimorfismo via herança tem suas vantagens (e desvantagens), a principal delas é deixar o código limpo quando a herança é aplicada corretamente, ou seja, entre classes relacionadas.

Apesar de alguns métodos definidos na classe base não serem requeridos por algumas subclasses, depois da aplicação do método desse artigo. Pode ser que esse modelo de código melhor se encaixe para a lógica de negócio que seu projeto tem de utilizar.

Nesse contexto, não deixe de aplicar essa melhoria por causa de alguns métodos extras na superclasse (ou Interface). As refatorações, muitas vezes, vão melhorar o código para uma próxima refatoração.

Outros artigos da série

Abaixo listo os artigos dessa série, com outras refatorações, que já foram liberados:

Internalizar Singleton

Mover Embelezamento Para Decorator

Substituir Condicionais que Alteram Estado por State

Introduzir Objeto Nulo

Unificar Interfaces Com Adapter

Extrair Adapter

Mover Conhecimento de Criação Para Factory

Substituir Notificações Hard-Coded Por Observer

Substituir Código de Tipo Por Classe

Extrair Parâmetro

Limitar Instanciação Com Singleton

Mover Acumulação Para Parâmetro Coletor

Compor Method

Formar Template Method

Substituir Lógica Condicional Por Strategy

Introduzir Criação Polimórfica com Factory Method

Encapsular Classes Com Factory

Encadear Construtores

Substituir Construtores Por Métodos de Criação

Fontes

Refatoração Para Padrões

Vlw.

Receba em primeira mão, e com prioridade, os conteúdos Android exclusivos do Blog.
Email inválido

Relacionado

Refatoração Para PadrõesRefatoração Para PadrõesLivros
Facebook Login, Firebase Android - Parte 5Facebook Login, Firebase Android - Parte 5Android
Google SignIn API, Firebase Android - Parte 6Google SignIn API, Firebase Android - Parte 6Android
Twitter Login (Fabric), Firebase Android - Parte 7Twitter Login (Fabric), Firebase Android - Parte 7Android

Compartilhar

Comentários Facebook

Comentários Blog

Para código / script, coloque entre [code] e [/code] para receber marcação especifica.
Forneça seu nome válido.
Forneça seu email válido.
Forneça o comentário.
Enviando, aguarde...