Pregunta ¿Cuándo usar un Constructor y cuándo usar el método getInstance () (métodos estáticos de fábrica)?


  1. Cuándo y cómo deberíamos usar un Constructor

    Foo bar = new Foo();
    
  2. 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, yo siempre uso el 1er camino, pero cuándo usar el 2º modo?


76
2017-07-02 22:03


origen


Respuestas:


Todo el mundo parece centrarse en singletons, mientras que creo que la pregunta es en realidad sobre constructor vs métodos estáticos de fábrica.

Esto es en realidad Punto 1: Considere métodos de fábrica estáticos en lugar de constructores de Java efectivo por Joshua Bloch:

Punto 1: Considere métodos de fábrica estáticos en lugar de constructores

La forma normal de una clase para permitir un   cliente para obtener una instancia de sí mismo   es proporcionar un constructor público.   Hay otra técnica que debería   ser parte de cada programador   kit de herramientas. Una clase puede proporcionar un público    método estático de fábrica, que es simplemente un método estático que devuelve un   instancia de la clase. Aquí hay un simple   ejemplo de Boolean (el en caja   clase primitiva para el tipo primitivo    boolean) Este método traduce un   valor primitivo booleano en una    Boolean referencia de objeto:

public static Boolean valueOf(boolean b) {
    return b ? Boolean.TRUE : Boolean.FALSE;
}

Tenga en cuenta que un método de fábrica estático es   no es lo mismo que Método de fábrica   patrón de Patrones de diseño   [Gamma95, p. 107]. La fábrica estática   método descrito en este artículo no tiene   equivalente directo en Diseño   Patrones.

Una clase puede proporcionar a sus clientes   métodos de fábrica estáticos en lugar de, o   además de, constructores.   Proporcionar un método de fábrica estático   en lugar de un constructor público tiene   ambas ventajas y desventajas.

Ventajas (citando el libro):

  • Una ventaja de los métodos de fábrica estáticos es que, a diferencia de los constructores, tienen nombres.
  • Una segunda ventaja de los métodos de fábrica estáticos es que, a diferencia de los constructores, no están obligados a crear un nuevo objeto cada vez que se invocan.
  • Una tercera ventaja de los métodos de fábrica estáticos es que, a diferencia de los constructores, pueden devolver un objeto de cualquier subtipo de su tipo de devolución.
  • Una cuarta ventaja de los métodos de fábrica estáticos es que reducen la verbosidad de crear instancias de tipo parametrizadas.

Desventajas (aún citando el libro):

  • La principal desventaja de proporcionar solo métodos de fábrica estáticos es que las clases sin constructores públicos o protegidos no se pueden subclasificar.
  • Una segunda desventaja de los métodos de fábrica estáticos es que no son fácilmente distinguible de otros métodos estáticos.

87
2017-07-02 23:16



Tienes dos preguntas: ¿cuándo debería llamada un getInstance() método, y cuando debería crear ¿uno?

Si estás decidiendo si llamar un getInstance() método, es fácil. Solo necesita leer la documentación de la clase para saber cuándo debe llamarla. Por ejemplo, NumberFormat proporciona un constructor y un getInstance() método; el getInstance() método le dará un localizado NumberFormat. por Calendar, por otro lado, el constructor está protegido. Tú tener llamar getInstance() para obtener uno.

Si estás decidiendo si crear un getInstance() método, debe decidir lo que está tratando de lograr. Tampoco tú no lo hagas quiero que las personas llamen a tu constructor (estás creando un semifallo o una fábrica), o no te importa (como en NumberFormat arriba, donde están inicializando algunos objetos para la conveniencia de la persona que llama).


¿Larga historia corta? No te preocupes por crear getInstance() métodos en tu propio código. Si llega el momento en que serán útiles, lo sabrá. Y, en general, si poder llamar al constructor de una clase, se supone que debes estar haciendo eso, incluso si la clase proporciona un getInstance() método.


7
2017-07-02 22:08



Los usos de los métodos getInstance:

Pero la mayor parte del tiempo tu objetivo 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 métodos hacen esto, ya que en realidad devuelven instancias de DecimalFormat.

U2: Problemas 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 ella a través de su método getInstance y no hará referencia a ninguna interfaz, no podrá cambiarla para otra implementación.


7
2017-07-02 22:14



Si puede usar ambos, parece una implementación deficiente patrón singleton.

Utilice la segunda opción si tiene la intención de tener solo una única instancia de la clase en su sistema y luego haga que el constructor sea privado.

Use 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 úselos si realmente solo existiera una instancia en el sistema, de lo contrario limitaría las posibilidades de reutilización de su clase en otros proyectos. Parece interesante poder llamar a getInstance desde cualquier lugar de su proyecto, pero eso no aclara quién posee realmente esa instancia: nadie y / o todo. Si tiene muchos solteros en un proyecto, puede apostar que el sistema está mal diseñado (generalmente). Los Singletons se deben usar con cuidado, se aplica el mismo consejo que para las variables globales.


6
2017-07-02 22:04



Un caso en el que siempre prefiero una fábrica estática sobre un constructor habitual es cuando sé que la construcción del objeto se ralentizará. Hago una inicialización simple en el constructor, pero si necesito crear algo pesado, usaré un método estático y documentaré el comportamiento.


1
2018-05-11 09:43



Singletons son malvados. Los problemas que he visto al respecto no se refieren a la reutilización o extensibilidad de un sistema (aunque podría ver cómo podría ocurrir), más aún porque no puedo contar la cantidad de veces que he visto errores desconocidos en un sistema que surge de singletons.

Si necesita usar un singleton, asegúrese de que su alcance es extremadamente estrecho, es decir, limite juiciosamente la cantidad de otros objetos en su sistema que lo conocen.


0
2017-07-02 22:20