2011-01-19 8 views
8

Leí el artículo Abstract Factory, Template Style de Jim Hyslop y Herb Sutter. Esta fábrica se implementa como Singleton. Proporcionaron una manera fácil de registrar clases automáticamente con la clase de ayuda RegisterInFactory.GenericFactory como Singleton

Ahora he leído varias veces que los Singletons deberían evitarse, algunos incluso los consideran como Anti-Patrones y que solo existen algunos casos en los que son útiles. ¿Es este uno de ellos? ¿O hay un enfoque alternativo que proporciona una manera tan fácil de autoregistrar clases?

+0

Tengo curiosidad por saber a qué punto de usted se refiere a que "Deberían evitarse los Singletons" ... – YeenFei

+0

"Deberían evitarse los Singletons" al igual que las variables globales. Una fábrica abstracta es más como un servicio global. Después de la inicialización (Registro), todos los clientes solo leen (solicite objetos). Creo que Abstract Factory es uno de los casos en que un Singleton es útil. – hansmaad

+0

es decir, http://stackoverflow.com/questions/86582/singleton-how-should-it-be -used o http://blogs.msdn.com/b/scottdensmore/archive/2004/05/25/140827. aspx – P3trus

Respuesta

2

Como siempre para este tipo de temas, no hay una respuesta que se aplique a todos los problemas. Algunos dijeron que debería evitarse el singleton cuando se usan como acceso a un servicio. Es un uso que es similar al uso de variables globales. De esta manera se enmascara el hecho de que se utiliza el servicio X en su aplicación:

// in header 
class MyUsefulClass 
{ 
    public: 
    void doSomethingUseful(); 
}; 

// in .cpp 
MyUsefulClass::doSomethingUseful() 
{ 
    // ... 
    MyWonderfulService::instance().doService1(); 
    // ... 
    MyWonderfulService::instance().doService2(); 
} 

Se crea un acoplamiento con MyWonderfulService que los usuarios de su clase no pueden adivinar. Por otra parte, no se puede probar fácilmente su clase útil con un servicio de simulacro ...

Es por eso por lo general prefieren dependancy inversion:

// in header 
class MyUsefulClass 
{ 
    public: 
    void setServiceToUse(MyService&); 
    void doSomethingUseful(); 

    // [...] 
}; 

// in .cpp 
MyUsefulClass::doSomethingUseful() 
{ 
    // ... 
    _myService->doService1(); 
    // ... 
    _myService->doService2(); 
} 

De esta manera se considera generalmente como un mejor acoplamiento entre la clase es más ligero. Sin embargo, para algunos servicios, que son bien conocidos por su amplio uso en un marco, es más simple utilizar un singleton. Tiene sentido para un solo servicio que es el servicio que le da acceso a todos los demás servicios en un marco, por ejemplo ^^ A menudo se utiliza para servicios técnicos como el registro, por ejemplo.

MY2C

Editar: leí el artículo, ya que la atención se centra en AbstractFactories, el uso de un producto único es casual, no es una decisión de diseño. Es comprensible en un artículo en el que no quieres escribir cosas que no te lleven a tu punto.

+0

Para tener la autorregistro como se muestra en el artículo, necesito el acceso global, pero no necesito que sea la única instancia. Una alternativa sería, por lo tanto, proporcionarlo como un estándar como std :: cout que me permita usarlo, pero no me impide usar uno si es necesario. ¿O hay una tercera vía, tal vez una forma superior de lograr este autoregistro? – P3trus

+0

@ p3trus: Agregaré un ejemplo concreto en mi respuesta cuando tenga tiempo ... Solo intente un sistema global por ahora. Yo personalmente uso la inversión de la desviación siempre ... – neuro