Refatoração de Código: Encadear Construtores

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: Encadear Construtores

Refatoração de Código: Encadear Construtores

Vinícius Thiengo
(1189)
Go-ahead
"Uma vez que nós aceitamos nossos limites, nós vamos além deles."
Albert Einstein
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
Ano2017
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 continuo a série de conteúdos falando sobre refatoração de código, aqui, mais especificamente, sobre o método de refatoração Encadear Construtores, que por sinal é bem simples e útil.

Apesar de estar na categoria Android do Blog, os artigos dessa série são úteis para qualquer linguagem de programação sendo utilizada junto ao paradigma de programação orientação a objetos.

Tópicos presentes no artigo:

Motivação

O objetivo desse método de refatoração é diminuir (ou eliminar) código duplicado dentro de construtores de uma classe. O problema de código duplicado é o principal motivo para a existência de vários padres de projeto. O problema é realmente descoberto no momento da atualização do software.

Um simples exemplo em texto, do problema. Segue:

Foi adicionado mais um atributo a classe e um dos construtores dela trabalha a inicializa esse novo atributo, porém as outras sobrecargas de construtores, com código repetido, não passaram pela atualização e o novo atributo não é referenciado nesses.

O que temos agora é um provável bug, pois caso um outro construtor seja utilizado para criar a instância da classe e logo depois um método que utiliza esse novo atributo seja invocado, teremos no mínimo uma saída de dados inconsistente.

Código de exemplo

Vamos utilizar um software de empréstimo bancário, mais precisamente parte do código desse software. Com esse software é possível criar instâncias de Empréstimo que podem trabalhar de diferentes maneiras dependendo do construtor utilizado. Essas maneiras distintas de trabalho representam os possíveis tipos de empréstimos da entidade financeira. Abaixo o código da classe Emprestimo:

public class Emprestimo {
private Estrategia estrategia;
private double obrigacao;
private double paraSaldar;
private int escalaDeRisco;
private Date vencimento;
private Date expiracao;

public Emprestimo( double obrigacao, int escalaDeRisco, Date vencimento ){
this.obrigacao = obrigacao;
this.escalaDeRisco = escalaDeRisco;
this.vencimento = vencimento;
}

public Emprestimo( double obrigacao, int escalaDeRisco, Date vencimento, Date expiracao ){
this.obrigacao = obrigacao;
this.escalaDeRisco = escalaDeRisco;
this.vencimento = vencimento;
this.expiracao = expiracao;
}

public Emprestimo( double obrigacao, double paraSaldar, int escalaDeRisco, Date vencimento, Date expiracao ){
this.obrigacao = obrigacao;
this.paraSaldar = paraSaldar;
this.escalaDeRisco = escalaDeRisco;
this.vencimento = vencimento;
this.expiracao = expiracao;
}

public Emprestimo( Estrategia estrategia, double obrigacao, int escalaDeRisco, Date vencimento, Date expiracao ){
this.estrategia = estrategia;
this.obrigacao = obrigacao;
this.escalaDeRisco = escalaDeRisco;
this.vencimento = vencimento;
this.expiracao = expiracao;
}

public Emprestimo( Estrategia estrategia, double obrigacao, double paraSaldar, int escalaDeRisco, Date vencimento, Date expiracao ){
this.estrategia = estrategia;
this.obrigacao = obrigacao;
this.paraSaldar = paraSaldar;
this.escalaDeRisco = escalaDeRisco;
this.vencimento = vencimento;
this.expiracao = expiracao;
}

/* TODO */
}

Note que vamos utilizar somente a parte necessária do código para a explicação do método de refatoração, por isso os “…” logo no final da classe.

Mecânica

O primeiro passo é encontrar o construtor que tem um número de atributos que atenda a todos os outros construtores, mesmo que em alguns casos os valores null, 0 ou false (valores padrões em objetos e primitivos no Java) tenham de ser fornecidos por esses outros construtores.

Curiosidade:

Se você buscar em outras literaturas conteúdo sobre esse método de refatoração logo vai perceber que ele não tem esse primeiro passo de diretamente buscar o construtor correto. Na verdade o recomendado em outras fontes é ir verificando de dois em dois construtores para então ajustar o código dos construtores por completo. Aqui optei por simplificar o processo, pois o resultado final será o mesmo: ter um construtor que atenda a todos os outros.

Caso o construtor que tenha todos os parâmetros de entrada necessários para atender aos outros não exista, então crie um, porém coloque o modificador de acesso dele como private (esse passo do private é opcional e será explicado mais a frente no decorrer desse artigo).

Note que somente no caso da criação de um novo construtor base é que ele já inicia como private, se esse construtor já existisse, ainda seria necessário a aplicação do passo dois do método de refatoração deste artigo.

Ainda no primeiro passo, depois de encontrado ou criado o construtor base, utilize ele nos outros construtores para ao menos ser o algoritmo responsável pela inicialização das variáveis de instância.

Em nosso projeto de exemplo, o último construtor apresentado no código pode ser utilizado por todos os outros construtores, logo, aplicando o método de refatoração proposto aqui nós temos o seguinte novo código para a classe Emprestimo:

public class Emprestimo {
private Estrategia estrategia;
private double obrigacao;
private double paraSaldar;
private int escalaDeRisco;
private Date vencimento;
private Date expiracao;

public Emprestimo( double obrigacao, int escalaDeRisco, Date vencimento ){
this( null, obrigacao, 0.0, escalaDeRisco, vencimento, null );
}

public Emprestimo( double obrigacao, int escalaDeRisco, Date vencimento, Date expiracao ){
this( null, obrigacao, 0.0, escalaDeRisco, vencimento, expiracao );
}

public Emprestimo( double obrigacao, double paraSaldar, int escalaDeRisco, Date vencimento, Date expiracao ){
this( null, obrigacao, paraSaldar, escalaDeRisco, vencimento, expiracao );
}

public Emprestimo( Estrategia estrategia, double obrigacao, int escalaDeRisco, Date vencimento, Date expiracao ){
this( estrategia, obrigacao, 0.0, escalaDeRisco, vencimento, expiracao );
}

public Emprestimo( Estrategia estrategia, double obrigacao, double paraSaldar, int escalaDeRisco, Date vencimento, Date expiracao ){
this.estrategia = estrategia;
this.obrigacao = obrigacao;
this.paraSaldar = paraSaldar;
this.escalaDeRisco = escalaDeRisco;
this.vencimento = vencimento;
this.expiracao = expiracao;
}

/* TODO */
}

O segundo passo é referente a verificação das chamadas de códigos clientes a esses construtores, mais precisamente verificar se há ou não chamadas ao nosso construtor base (o que é utilizado por todos os outros construtores), caso não encontrada alguma chamada a esse construtor, coloque o modificador de acesso a ele como private.

Por que o private?

Colocar entidades de uma classe como private alivia em muito o processo de refatoração do projeto de software. Tendo em mente que mesmo utilizando IDEs sofisticadas, as entidades com tipo de acesso private lhe permitem evitar uma busca abrangente em todo o projeto para poder saber se será trivial ou não o passo de mover o atributo ou método para outra parte do software.

Kent Beck em “Padrões de Implementação” indica que no desenvolvimento do software devemos ir aumentando a abrangência do modificador de acesso das entidades do projeto somente quando forem necessárias, ou seja, todas começam em private, logo depois, surgindo a necessidade, verificar se protected é o suficiente para suprir tal necessidade. E assim por diante até chegar ao modificador de acesso public, o mais abrangente.

Com isso aplicamos o método de refatoração proposto. Para completar a refatoração da classe coloque intenção na criação de objetos, veja o artigo Substituir Construtores Por Métodos de Criação, para entender essa refatoração.

Conclusão

Como já informado: código duplicado é um problema tão sério que a maior parte dos padrões de projeto existem devido a ele.

Não existe um único padrão ou qualquer outra estratégia isolada que consiga evitar de forma definitiva os códigos duplicados de um projeto de software. Na verdade são cooperações entre técnicas de código limpo que vão permitir esse “de forma definitiva”  para o fim dos códigos repetidos de seu algoritmo se tornar algo real.

Uma dessas técnicas, simples de entender e de utilizar, é o método de refatoração Encadear Construtores, logo, o utilize sempre que enxergado o padrão de código que permite a aplicação dele.

Pode ser que haja um outro construtor de seu projeto que tenha um código muito diferente e que não seja possível reaproveitar nada. Não há problemas, utilize a técnica aqui com os construtores que seja possível a implementação dela. A ideia está em diminuir ao máximo o número de códigos duplicados.

Outros artigos da série

Listo abaixo todos os métodos de refatoração já apresentados 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

Extrair Parâmetro

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

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

Engenharia de Software: Código Limpo na PráticaEngenharia de Software: Código Limpo na PráticaDesenvolvimento Web
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
Refatoração de Código: Substituir Construtores Por Métodos de CriaçãoRefatoração de Código: Substituir Construtores Por Métodos de CriaçãoAndroid

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