Construtores semânticos: aprimorando a criação de objetos
Tags: java, programming, productivity
Published: 2024-05-24 20:28:02


Construtores tradicionais muitas vezes resultam em código difícil de ler e entender quando possuem múltiplos parâmetros. Construtores semânticos oferecem uma solução para este problema "nomeando" os construtores de forma descritiva e clara. Isso não apenas melhora a legibilidade, mas também facilita a manutenção do código, pois o propósito de cada instância fica claro pelo nome do método.

Quando uma classe possui múltiplos parâmetros de diferentes tipos, existe grande chance de ocorrerem construtores ambíguos e propensos a erros. Por exemplo, considere a classe _VerificadorAssinaturaDigital_:
```java
public class VerificadorAssinaturaDigital {
	private final String nomeArquivoConteudo;
	private final byte[] binarioArquivoConteudoAssinado;
	private final String nomeArquivoAssinatura;
	private final byte[] binarioArquivoAssinatura;

	public VerificadorAssinaturaDigital(final String nomeArquivoConteudo, final byte[] binarioArquivoConteudoAssinado, final String nomeArquivoAssinatura, final byte[] binarioArquivoAssinatura) {
		this.nomeArquivoConteudo = nomeArquivoConteudo;
		this.binarioArquivoConteudoAssinado = binarioArquivoConteudoAssinado;
		this.nomeArquivoAssinatura = nomeArquivoAssinatura;
		this.binarioArquivoAssinatura = binarioArquivoAssinatura;
	}
}
```
Ao instanciar a classe _VerificadorAssinaturaDigital_, pode ser difícil lembrar a ordem e o propósito de cada parâmetro, especialmente em projetos maiores ou quando a classe tem muitos parâmetros:
```java
VerificadorAssinaturaDigital verificador = new VerificadorAssinaturaDigital("documento", BINARIO, "nomeArquivoAssinatura", BINARIO2);
```
Aqui, não é imediatamente óbvio quais são os valores passados ou seu propósito. Este problema é amplificado à medida que o número de parâmetros aumenta, potencialmente levando a erros e dificultando a leitura do código.

## Métodos de Fábrica Estáticos
"Métodos de fábrica estáticos, como descrito por Joshua Bloch em seu livro _Effective Java_, possuem nomes ao contrário dos construtores tradicionais." Esta técnica consiste em tornar o construtor privado e utilizar métodos estáticos para retornar uma nova instância do objeto, mas com nomes descritivos que indicam objetivamente a finalidade da criação. Por exemplo, na classe _VerificadorAssinaturaDigital_, poderíamos definir métodos de fábrica assim:
```java
public class VerificadorAssinaturaDigital {
	private final String nomeArquivoConteudo;
	private final byte[] binarioArquivoConteudoAssinado;
	private final String nomeArquivoAssinatura;
	private final byte[] binarioArquivoAssinatura;

	private VerificadorAssinaturaDigital(final String nomeArquivoConteudo, final byte[] binarioArquivoConteudoAssinado, final String nomeArquivoAssinatura, final byte[] binarioArquivoAssinatura) {
		this.nomeArquivoConteudo = nomeArquivoConteudo;
		this.binarioArquivoConteudoAssinado = binarioArquivoConteudoAssinado;
		this.nomeArquivoAssinatura = nomeArquivoAssinatura;
		this.binarioArquivoAssinatura = binarioArquivoAssinatura;
	}

	public static VerificadorAssinaturaDigital criarParaAssinaturaPdf(final String nomeArquivoConteudo, final byte[] binarioArquivoConteudoAssinado) {
		return new VerificadorAssinaturaDigital(nomeArquivoConteudo, binarioArquivoConteudoAssinado);
	}

	public static VerificadorAssinaturaDigital criarParaAssinaturaCms(final String nomeArquivoConteudo, final byte[] binarioArquivoConteudoAssinado, final String nomeArquivoAssinatura, final byte[] binarioArquivoAssinatura) {
		return new VerificadorAssinaturaDigital(nomeArquivoConteudo, binarioArquivoConteudoAssinado, nomeArquivoAssinatura, binarioArquivoAssinatura);
	}
}
```
Uma vez que é possível "nomear" os construtores, tornando-os semânticos, ao bater o olho no nome do método é possível saber para qual propósito aquele objeto será construído:
```java
VerificadorAssinaturaDigital verificadorAssinaturaPdf = VerificadorAssinaturaDigital.criarParaAssinaturaPdf();
VerificadorAssinaturaDigital verificadorAssinaturaCms = VerificadorAssinaturaDigital.criarParaAssinaturaCms();
```
## Benefícios dos Construtores Semânticos
Os construtores semânticos oferecem várias vantagens significativas em comparação com os construtores tradicionais:

1.  **Legibilidade**: Os métodos de fábrica estáticos têm nomes descritivos que tornam o código mais fácil de ler e entender.
2.  **Manutenção**: Facilita a manutenção, pois os métodos nomeados explicitamente deixam claro o propósito de cada instância, reduzindo a chance de erros.
3.  **Flexibilidade**: Permite adicionar novos métodos de fábrica sem alterar o construtor original, promovendo a extensibilidade do código.
4.  **Clareza**: A utilização de métodos de fábrica elimina a ambiguidade sobre quais parâmetros estão sendo passados, especialmente em classes com muitos atributos.

## Conclusão
Construtores semânticos proporcionam uma maneira mais legível e intuitiva de criar objetos. Utilizando métodos de fábrica estáticos com nomes descritivos, esses construtores melhoram significativamente a clareza e a manutenção do código. Eles facilitam a leitura, reduzem a ambiguidade e diminuem a chance de erros. Além disso, promovem a flexibilidade na adição de novos métodos de criação sem modificar o construtor original.

## Referências
 - Bloch, Joshua. _Effective Java_. 3ª edição, Addison-Wesley Professional, 2018