Cuando y como debemos usar un constructor
Foo bar = new Foo();
Y cuándo y cómo deberíamos usar getInstance () (métodos de fábrica estáticos)
Foo bar = Foo.getInstance();
¿Cuál es la diferencia entre estos dos? Siempre he usado un constructor, pero ¿cuándo debería usarlo getInstance()
?
getInstance()
o estás escribiendo un método llamadogetInstance()
?Foo.newInstance()
.Foo.getInstance()
es una convención para obtener la instancia singleton de una clase. Debería corregir su ejemplo y utilizarloFoo.newInstance()
en su lugar.Respuestas:
Todo el mundo parece centrarse en los singletons, mientras que creo que la pregunta es en realidad sobre métodos de constructor vs estáticos de fábrica .
Este es en realidad el elemento 1: considere los métodos de fábrica estáticos en lugar de los constructores de Effective Java de Joshua Bloch:
Ventajas (citando el libro):
Desventajas (aún citando el libro):
fuente
protected
subclasificación, pero ¿el código del cliente obtiene alguna ventaja real al crear un nuevo objeto y llamar a su constructor, en lugar de llamar a un método de fábrica estático? Me parece que una llamada a un constructor encadenado es semánticamente un método de instancia, mientras que la secuencia "crear un objeto unificado y llamar a su constructor" es semánticamente equivalente a una llamada a un método de fábrica estático.Tiene dos preguntas: ¿cuándo debo llamar a un
getInstance()
método y cuándo debo crear uno?Si está decidiendo si llamar a un
getInstance()
método, es fácil. Solo necesita leer la documentación de la clase para saber cuándo debe llamarlo. Por ejemplo,NumberFormat
proporciona un constructor y ungetInstance()
método; elgetInstance()
método le dará un archivoNumberFormat
. PorqueCalendar
, por otro lado, el constructor está protegido. Usted tiene que llamargetInstance()
para conseguir uno.Si está decidiendo si crear un
getInstance()
método, debe decidir qué está tratando de lograr. O no quiere que la gente llame a su constructor (está creando un singleton o una fábrica ), o no le importa (como en el casoNumberFormat
anterior, donde están inicializando algunos objetos para la conveniencia del llamador).¿Larga historia corta? No se preocupe por crear
getInstance()
métodos en su propio código. Si llega el momento en que serán útiles, lo sabrás. Y, en general, si puede llamar al constructor de una clase, probablemente se supone que debe hacerlo, incluso si la clase proporciona ungetInstance()
método.fuente
Los usos de los métodos getInstance:
Pero la mayoría de las veces su objeto será un simple POJO y el uso de constructores públicos es la solución más práctica y obvia.
U1: getInstance de otra clase
Para devolver una instancia de una clase diferente:
public class FooFactory { public static Foo getInstance() { return new Foo(); } }
NumberFormat.getInstance
Los métodos hacen esto ya que en realidad devuelven instancias deDecimalFormat
.U2: Problemas de singleton
El patrón singleton restringe muchos de los beneficios de la programación orientada a objetos. Los singleton generalmente tienen constructores privados, por lo tanto, no puede extenderlos. Como accederá a él a través de su método getInstance y no hará referencia a ninguna interfaz, no podrá cambiarlo por otra implementación.
fuente
Si puede usar ambos, entonces suena como un patrón singleton mal implementado .
Utilice la segunda opción si tiene la intención de tener una sola instancia de la clase en su sistema y luego hacer que el constructor sea privado.
Utilice el primero para permitir la construcción de varios objetos de la clase.
PERO no le dé a su clase las dos posibilidades.
Tenga cuidado de no usar en exceso los singleton, solo utilícelos si realmente solo existirá una instancia en el sistema, de lo contrario limitaría las posibilidades de reutilización de su clase en otros proyectos. Suena interesante poder llamar a getInstance desde cualquier lugar de su proyecto, pero eso deja poco claro quién es el propietario de esa instancia: nadie y / o todos. Si tiene muchos singleton en un proyecto, puede apostar a que el sistema está mal diseñado (generalmente). Los singleton deben usarse con cuidado, se aplican los mismos consejos que para las variables globales.
fuente
Un caso en el que siempre prefiero una fábrica estática sobre un constructor normal es cuando sé que la construcción del objeto será lenta. Hago una inicialización simple en el constructor, pero si necesito crear algo pesado, usaré un método estático y documentaré el comportamiento.
fuente
Los singleton son malvados. Los problemas que he visto a su alrededor no se refieren a la reutilización o la capacidad de ampliación de un sistema (aunque pude ver cómo podría ocurrir eso), más bien que no puedo contar la cantidad de veces que he visto errores oscuros en un sistema que surgen de singletons.
Si necesita usar un singleton, asegúrese de que su alcance sea extremadamente estrecho, es decir, limite juiciosamente el número de otros objetos en su sistema que lo conocen.
fuente