2009-09-01 10 views
6

Desde la perspectiva de un usuario final de API que necesita "obtener una instancia" de una clase Singleton, ¿prefiere "obtener" una propiedad de .Instance o "llamar" a. GetInstance() ¿Método?C# Singleton "GetInstance" Método o "Instancia" de la propiedad?

public class Bar 
{ 
    private Bar() { } 

    // Do you prefer a Property? 
    public static Bar Instance 
    { 
     get 
     { 
      return new Bar(); 
     } 
    } 

    // or, a Method? 
    public static Bar GetInstance() 
    { 
     return new Bar(); 
    } 
} 
+2

"obtener una instancia" realmente debería ser "obtener la instancia" - y el 'nuevo' es un poco engañoso ;-p –

+0

@Marc Gravell - de acuerdo. punto bien tomado. thx – jlang

+0

Por favor, piensen dos veces antes de escribir un Singleton. He visto casos en los que han forzado el uso de pruebas de integración sobre pruebas unitarias: los Singleton acceden a una base de datos y otras clases están conectadas a ellas. Ver http://stackoverflow.com/questions/137975/what-is-so-bad-about-singletons – TrueWill

Respuesta

14

En C#, que ahora preferiría .Instance, ya que se ajusta a las directrices generales.

+1

+1 de acuerdo.Passing parámetros tampoco deberían ser necesarios. – Mickel

+0

@Mickel dependency injection acoplado con un patrón singleton? –

+0

Personalmente, nunca he escrito un 'Singleton' para mi propia legitimidad, y generalmente tengo dudas sobre su necesidad. –

3

Depende. ¿Necesita pasar parámetros? Si es así, yo haría GetInstance(). Si no es así, probablemente no importe (al menos desde el punto de vista de una llamada, ya que en realidad son ambos métodos; sin embargo, importa si está tratando de estar más basado en estándares y, en ese caso, un instancia parece ser mejor).

0

Prefiero la propiedad, estos son patrones estándar.

4

Como con casi todo, depende :)

Si el singleton es-lazy cargado y representa más de una cantidad trivial de trabajo para crear una instancia, a continuación, GetInstance() es más apropiado, como una invocación de método indica el trabajo se está haciendo.

Si simplemente estamos enmascarando para proteger la instancia de singleton, es preferible una propiedad.

+0

Pero específicamente para un singleton, solo la primera invocación debería hacer el trabajo. Las siguientes invocaciones deberían simplemente devolver la instancia preparada previamente. –

+0

@ Por supuesto, pero en un singleton con carga lenta la persona que llama no sabe si se ha instanciado, por lo que cada llamada es potencialmente la más pesada. –

13

Si desea crear singleton, no puede simplemente devolver un nuevo objeto en cada llamada a GetInstance o Instance getter de propiedad. Debe hacer algo como esto:

public sealed class Bar 
{ 
    private Bar() { } 

    // this will be initialized only once 
    private static Bar instance = new Bar(); 

    // Do you prefer a Property? 
    public static Bar Instance 
    { 
     get 
     { 
      return instance; 
     } 
    } 

    // or, a Method? 
    public static Bar GetInstance() 
    { 
     return instance; 
    } 
} 

Y realmente no importa qué manera de hacer que elija. Si prefiere trabajar con propiedades, elíjalo, si prefiere métodos, también estará bien.

+0

¿Estás seguro? Al principio pensé lo mismo, pero el constructor privado asegura que solo esa clase puede crear instancias de sí mismo. En cualquier caso, puede eliminar el constructor privado en el suyo. –

+2

Todos los puntos válidos; probablemente también debería ser 'sellado'. –

+0

@RaYell Creo que su código de muestra es solo para demostrar la diferencia entre la propiedad y el método. –

0

Como dijo @Rex, depende de la semántica que desee transmitir.

GetInstance() no implica necesariamente una instancia de singleton. Por lo tanto, usaría GetInstance() en el caso en que la creación de instancias ocurra a petición, el nuevo directo no es deseable y la instancia podría ser, pero no se garantiza que sea la misma. Los grupos de objetos también cumplen estos criterios. (De hecho, un singleton es una especialización de un conjunto de objetos con preservación de estado :-))

La propiedad Instancia estática, por otro lado, implica una identidad de instancia única e intacta.

Por cierto, como @RaYell mencionó que su código de muestra no es un singleton, por lo que no debería estar utilizando la propiedad Instance. Todavía puede usar el método GetInstance() en este caso, ya que serviría como una fábrica de instancias.

2
public class Singleton 
{ 

    private volatile static Singleton uniqueInstance; 
    private static readonly object padlock = new object(); 

    private Singleton() { } 

    public static Singleton getInstance() 
    { 
     if (uniqueInstance == null) 
     { 
      lock (padlock) 
      { 
       if (uniqueInstance == null) 
       { 
        uniqueInstance = new Singleton(); 
       } 
      } 
     } 
     return uniqueInstance; 
    } 
} 

En el código anterior doble control se implementa, en primer lugar se comprueba si se se crea una instancia y si no se ha establecido bloquear .Una vez en este bloque

   if (uniqueInstance == null) 
       { 
        uniqueInstance = new Singleton(); 
       } 

si la instancia es null luego créelo.

Además, la variable uniqueInstance se declara volátil para garantizar que la asignación a la variable de instancia finalice antes de que se pueda acceder a la variable de instancia.

+0

Bonito bloqueo de doble verificación.Aunque si solo necesita crear una instancia de su singleton, use: private static readonly Singleton uniqueInstance = new Singleton(); – bryanbcook

Cuestiones relacionadas