Eu excluí recentemente uma resposta minha sobre Java na Code Review , que começou assim:
private Person(PersonBuilder builder) {
Pare. Bandeira vermelha. Um PersonBuilder criaria uma Pessoa; conhece uma pessoa. A classe Person não deve saber nada sobre um PersonBuilder - é apenas um tipo imutável. Você criou um acoplamento circular aqui, onde A depende de B, que depende de A.
A Pessoa deve apenas inserir seus parâmetros; um cliente que esteja disposto a criar uma Pessoa sem construí-la deve poder fazer isso.
Eu recebi um voto negativo e disse que (citando) bandeira vermelha, por quê? A implementação aqui tem a mesma forma que Joshua Bloch demonstrou em seu livro "Effective Java" (item # 2).
Portanto, parece que a maneira correta de implementar um padrão de construtor em Java é tornar o construtor um tipo aninhado (não é disso que se trata esta pergunta) e criar o produto (a classe do objeto que está sendo construído ) dependem do construtor , assim:
private StreetMap(Builder builder) { // Required parameters origin = builder.origin; destination = builder.destination; // Optional parameters waterColor = builder.waterColor; landColor = builder.landColor; highTrafficColor = builder.highTrafficColor; mediumTrafficColor = builder.mediumTrafficColor; lowTrafficColor = builder.lowTrafficColor; }
A mesma página da Wikipedia para o mesmo padrão do Builder possui uma implementação totalmente diferente (e muito mais flexível) para C #:
//Represents a product created by the builder public class Car { public Car() { } public int Wheels { get; set; } public string Colour { get; set; } }
Como você pode ver, o produto aqui não sabe nada sobre uma Builder
classe e, apesar de tudo, pode ser instanciado por uma chamada direta do construtor, uma fábrica abstrata, ... ou um construtor - tanto quanto eu entendo, o O produto de um padrão criacional nunca precisa saber nada sobre o que está sendo criado.
Recebi o contra-argumento (que aparentemente é explicitamente defendido no livro de Bloch) de que um padrão de construtor poderia ser usado para refazer um tipo que teria um construtor inchado com dezenas de argumentos opcionais. Então, em vez de seguir o que pensei que sabia, pesquisei um pouco neste site e descobri que, como suspeitava, esse argumento não retém a água .
Então, qual é o problema? Por que apresentar soluções superprojetadas para um problema que nem deveria existir em primeiro lugar? Se tirarmos Joshua Bloch de seu pedestal por um minuto, podemos encontrar uma única razão válida e boa para unir dois tipos de concreto e chamá-lo de melhor prática?
Isso tudo cheira a programação de cultos de carga para mim.