Refatoração de Código: Extrair Parâmetro

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: Extrair Parâmetro

Refatoração de Código: Extrair Parâmetro

Vinícius Thiengo
(1276)
Go-ahead
"Quando o passado chamá-lo, deixe ir para a caixa postal. Não tem nada de novo para lhe dizer."
Mandy Hale
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 com o objetivo de obter maior performance nossa como programadores. Dessa vez abordando um outro simples método de refatoração, Extrair Parâmetro.

Antes de prosseguir ressalto que os artigos dessa série são válidos para qualquer algoritmo de qualquer linguagem de programação que trabalhe com orientação a objetos. Alguns métodos da série também funcionam com o paradigma procedural.

Tópicos presentes no artigo:

Motivação

Para instâncias de classes que têm atributos sendo preenchidos por objetos que são criados dentro da própria instância proprietária do atributo, porém esses objetos são criados com valores vindos como parâmetros de construtores ou métodos.

Para o caso descrito anteriormente utiliza-se o método de refatoração proposto aqui para injetar a dependência e remover o forte acoplamento.

Forte acoplamento tem um nome sério, realmente parece expressar um problema, mas ele é mesmo um problema que deve ser levado em conta?

Sim, tão ruim quanto código duplicado. Assuma que uma classe de seu projeto instancie, dentro dos códigos dela, uma outra classe. Essa instância é necessária para preencher um atributo importante no processamento de objetos do tipo da classe cliente.

Agora, como exemplo, altere o construtor dessa classe instanciada, digo, todos os construtores. Somente esse passo de atualizarão já é o suficiente para mostrar o que acontecerá com a classe cliente: o código dela deverá ser refatorado mesmo ela não sendo alvo da refatoração, tendo em mente que a classe fornecedora somente teve o construtor alterado, nada que deveria afetar a classe cliente.

Esse é um exemplo simples que mostra como a evolução do projeto fica prejudicada devido ao forte acoplamento entre classes.

Código de exemplo

Para seguir com a apresentação do método de refatoração desse artigo, um código de  domínio de problema de carros será utilizado como exemplo. Mais precisamente, uma classe, Carro:

public class Carro {
private String modelo;
private Marca marca = new Marca();
private Motor motor;

public Carro(String modelo, String marca, String tipoMotor, int cilindradas){
this.modelo = modelo;
this.marca.setNome( marca );
this.motor = new Motor( tipoMotor, cilindradas );
}

public void setMotor( String tipoMotor, int cilindradas ){
this.motor = new Motor( tipoMotor, cilindradas );
}
...
}

 

Note que para os atributos motor e marca as instâncias são criadas dentro do objeto proprietário. O principal problema nesse caso é o forte acoplamento criado entre os objetos das classes Carro, Marca e Motor.

A leitura do código também fica prejudicada, pois o número de parâmetros no construtor ou método aumenta.

Mecânica

Nosso primeiro passo na aplicação do método de refatoração Extrair Parâmetro é localizar atribuições de instâncias locais a atributos do objeto.

Todas as sentenças desse tipo devem estar dentro de métodos ou construtores. Caso alguma esteja fora, na declaração dos atributos, devemos movê-la para dentro de um método ou construtor.

Em nosso caso temos o atributo marca recebendo a instância do tipo Marca ainda na declaração dele. Logo vamos mover esse código para o construtor de Carro:

public class Carro {
private String modelo;
private Marca marca;
private Motor motor;

public Carro(String modelo, String marca, String tipoMotor, int cilindradas){
this.modelo = modelo;
this.marca = new Marca( marca );
this.motor = new Motor( tipoMotor, cilindradas );
}

public void setMotor( String tipoMotor, int cilindradas ){
this.motor = new Motor( tipoMotor, cilindradas );
}
...
}

 

Note que para adiantar o processo já assumi que existe na classe Marca um construtor que recebe como parâmetro de entrada uma String representando o nome da marca. Porém o código abaixo seria perfeitamente válido:

...
public Carro(String modelo, String marca, String tipoMotor, int cilindradas){
this.modelo = modelo;
this.marca = new Marca();
this.marca.setNome( marca );
this.motor = new Motor( tipoMotor, cilindradas );
}
...

 

Nosso segundo e último passo (apenas dois!) é adicionar parâmetros que terão como valor as respectivas instâncias necessárias para os atributos que estão sendo iniciados no construtor ou método da classe sendo refatorada, Carro.

Logo depois removeremos os parâmetros que não mais têm valor no objeto, os que eram utilizados para preencher as instâncias dos atributos. Segue código de Carro atualizado:

public class Carro {
private String modelo;
private Marca marca;
private Motor motor;

public Carro(String modelo, Marca marca, Motor motor){
this.modelo = modelo;
this.marca = marca;
this.motor = motor;
}

public void setMotor( Motor motor ){
this.motor = motor;
}
}

 

Note que a alteração deve ser feita em construtores e métodos.

Com isso atingimos nossos objetivos aplicando o método Extrair Parâmetro. São eles: fraco acoplamento entre as dependências e melhor leitura de código.

Um código cliente, antigo, das instâncias de Carro não mais faria isso:

...
public static void main( String[] args ){

...
carro = new Carro( "720i", "BMW", "v8", 55000 );
list.add( carro );
}
...

 

Para então passar a trabalhar da seguinte forma:

...
public static void main( String[] args ){
...
motor = new Motor( "v8", 55000 );
marca = new Marca( "BMW" );
carro = new Carro( "720i", marca, motor );
list.add( carro );
}
...

 

O algoritmo mais atual do cliente de instâncias de Carro apresenta mais linhas de código, porém essas não apresentam perda de performance e a leitura do código fica mais intuitiva, então é uma substituição perfeitamente válida e que preza pela leitura, código limpo.

Conclusão

O trabalho com injeção de dependência como o método Extrair Parâmetro prega, na verdade, é uma das práticas recomendadas de código limpo, muito devido a melhora de leitura do código, ou seja, não somente devido ao problema de forte acoplamento.

Tenha em mente que em média 90% dos gastos com a evolução de um software é com o tempo de leitura (entendimento) dele.

A refatoração apresentada aqui é do nível daquelas que não têm contra indicação, sempre deve ser aplicada assim que enxergado o problema de forte acoplamento.

E o problema de leitura de código prejudicada? Somente enxergando ele não é o suficiente para aplicarmos o método Extrair Parâmetro?

Caso o algoritmo não apresente junto o problema de forte acoplamento, então outra refatoração é que deve ser aplicada. Algumas vezes somente alterar os nomes de classes, métodos e variáveis, deixando o código autocomentado, ajuda em muito.

Outros artigos da série

Abaixo são listados todos os artigos já liberados dessa série de refatoração de código:

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

Unificar Interfaces

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

Livro 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

Código Limpo - Habilidades Práticas do Agile SoftwareCódigo Limpo - Habilidades Práticas do Agile SoftwareLivros
Padrões de Implementação - Um Catálogo de Padrões Indispensável Para o Dia a Dia do ProgramadorPadrões de Implementação - Um Catálogo de Padrões Indispensável Para o Dia a Dia do ProgramadorLivros
Persistência Com Firebase Android - Parte 1Persistência Com Firebase Android - Parte 1Android
Recuperação de Senha, Firebase Atualizado - Parte 8Recuperação de Senha, Firebase Atualizado - Parte 8Android

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...