Recientemente comencé a leer Effective Java de Joshua Bloch. Me pareció muy interesante la idea del patrón Builder [Elemento 2 del libro]. Traté de implementarlo en mi proyecto pero hubo errores de compilación. Lo siguiente es, en esencia, lo que estaba tratando de hacer:
La clase con múltiples atributos y su clase de constructor:
public class NutritionalFacts {
private int sodium;
private int fat;
private int carbo;
public class Builder {
private int sodium;
private int fat;
private int carbo;
public Builder(int s) {
this.sodium = s;
}
public Builder fat(int f) {
this.fat = f;
return this;
}
public Builder carbo(int c) {
this.carbo = c;
return this;
}
public NutritionalFacts build() {
return new NutritionalFacts(this);
}
}
private NutritionalFacts(Builder b) {
this.sodium = b.sodium;
this.fat = b.fat;
this.carbo = b.carbo;
}
}
Clase donde trato de usar la clase anterior:
public class Main {
public static void main(String args[]) {
NutritionalFacts n =
new NutritionalFacts.Builder(10).carbo(23).fat(1).build();
}
}
Recibo el siguiente error del compilador:
se requiere una instancia de cierre que contenga efectivajava.BuilderPattern.NutritionalFacts.Builder NutritionalFacts n = new NutritionalFacts.Builder (10) .carbo (23) .fat (1) .build ();
No entiendo lo que significa el mensaje. Por favor explique. El código anterior es similar al ejemplo sugerido por Bloch en su libro.
java
design-patterns
builder-pattern
Swaranga Sarma
fuente
fuente
Respuestas:
Haz del constructor una
static
clase. Entonces funcionará. Si no es estático, requeriría una instancia de su clase propietaria, y el punto es no tener una instancia de la misma, e incluso prohibir hacer instancias sin el generador.Referencia: clases anidadas
fuente
Builder
estástatic
en el ejemplo en el libro (página 14, línea 10 en la 2da edición).Debe hacer que la clase Builder sea estática y también debe hacer que los campos sean finales y tener captadores para obtener esos valores. No proporcione definidores a esos valores. De esta manera tu clase será perfectamente inmutable.
Y ahora puede establecer las propiedades de la siguiente manera:
fuente
final
los campos solo tienen sentido si los campos siempre son necesarios durante la inicialización. Si no, entonces los campos no deberían serfinal
.Está intentando acceder a una clase no estática de forma estática. Cambiar
Builder
astatic class Builder
y debería funcionar.El uso de ejemplo que da falla porque no hay una instancia de
Builder
presente. Siempre se crea una instancia de una clase estática para todos los fines prácticos. Si no lo hace estático, deberá decir:Porque necesitarías construir uno nuevo
Builder
cada vez.fuente
Para generar un generador interno en Intellij IDEA, consulte este complemento: https://github.com/analytically/innerbuilder
fuente
Necesitas declarar la
Builder
clase interna comostatic
.Consulte alguna documentación para las clases internas no estáticas y las clases internas estáticas .
Básicamente, las instancias de clases internas no estáticas no pueden existir sin una instancia de clase externa adjunta.
fuente
Una vez que tenga una idea, en la práctica, puede encontrar que Lombok es
@Builder
mucho más conveniente.@Builder
le permite producir automáticamente el código requerido para que su clase sea instanciable con código como:Documentación oficial: https://www.projectlombok.org/features/Builder
fuente
Esto significa que no puede crear el tipo de cierre. Esto significa que primero debe crear una instancia de la clase "padre" y luego, desde esta instancia, puede crear instancias de clase anidadas.
Clases anidadas
fuente
La clase Builder debe ser estática. No tengo tiempo en este momento para probar el código más allá de eso, pero si no funciona, avíseme y volveré a analizarlo.
fuente
Personalmente prefiero usar el otro enfoque, cuando tienes 2 clases diferentes. Entonces no necesitas ninguna clase estática. Esto es básicamente para evitar escribir
Class.Builder
cuando tiene que crear una nueva instancia.Entonces, puedes usar tu constructor así:
fuente
Como muchos ya dijeron aquí, necesitas hacer la clase
static
. Solo una pequeña adición: si lo desea, hay una forma un poco diferente sin una estática.Considera esto. Implementando un constructor declarando algo así como los
withProperty(value)
creadores de tipos dentro de la clase y haciendo que devuelvan una referencia a sí mismo. En este enfoque, tiene una clase única y elegante que es un hilo seguro y conciso.Considera esto:
Compruébalo para ver más ejemplos de Java Builder .
fuente
Debe cambiar la clase de generador a generador de clase estática . Entonces funcionará bien.
fuente