2011-01-28 29 views
5

en C# que tiene que declarar todo en una clase para un patrón de ejemplo de la fábrica podría parecerse a:patrón de la fábrica adecuada en C++

namespace MySpace { 

public class CFactory 
{ 
    public static CFactory Current() 
    { 
    static CFactory singleton; 
    return singleton; 
    } 
    public CBase Create() { return null; } 
} 

} 

en C++ que no tienen esta limitación .. Por lo que es considerada "mala práctica "tener métodos de" fábrica "¿son funciones globales versus tenerlos como una clase?

ejemplo 1:

namespace MySpace { 

// factory method 
std::shared_ptr<CBase> CreateBase() { return NULL; } 

} 

ejemplo 2:

namespace MySpace { 

// factory class 
class CFactory 
{ 
public: 
    std::shared_ptr<CBase> CreateBase() { return NULL; } 
}; 

// factory method exposing class 
CFactory& GetFactory() 
{ 
    static CFactory singleton; 
    return singleton; 
} 

} 

ejemplo 3:

namespace MySpace { 

// factory class with no global function 
class CFactory 
{ 
public: 
    std::shared_ptr<CBase> CreateBase() { return NULL; } 

public: 
    static CFactory& getFactory() 
    { 
    static CFactory singleton; 
    return singleton; 
    } 
}; 

} 

la biblioteca std utiliza una gran cantidad de funciones globales para los "métodos de fábrica" ​​.. un ejemplo de esto sería std :: make_shared.

he utilizado antes y estoy simplemente no está seguro si uno se considera "mejor" sobre el otro

+0

Tiendo a poner un 'Foo * make()' estático o similar dentro de la clase base 'Foo'.Realmente no entiendo qué está pasando con el singleton en su segundo ejemplo ... –

+0

Agregué el ejemplo 3 para eliminar la función global para el singleton. mi atención se centra más en el patrón de fábrica, pero otros también se han confundido con el ejemplo 2. – BabelFish

Respuesta

3

Puede presumir de su uso en la biblioteca estándar que una fábrica mundial de espacio de nombres no es implícitamente mal. Nada impide que sea correcto.

Su enfoque de envolver la fábrica en una clase es un organizacional cambio. La organización en sí no es ni buena ni mala. Se puede hacer bien o mal.

Debería estar bien haciendo lo que le parezca cómodo para su contexto. También he visto que ambos enfoques se usaron muchas veces y ninguno fue particularmente problemático.

0

Aquí está un ejemplo de una forma de implementar Singleton en C++
De esta manera se puede evitar global.
Espero que esto ayude.

/* header file */ 

#ifndef EXAMPLE_H 
#define EXAMPLE_H 

class example 
{ 
private: 
    example(); // constructor 
public: 
    ~example(); // destructor 
    static example *getExampleObject(); 
} 
#endif 

/* cpp file */ 
#include "example.h" 

example *example::getExampleObject() 
{ 
    static example *theInstance = NULL; 
    if(theInstance == NULL) 
    { 
     theInstance = new example(); 
    } 
    return theInstance; 
} 
+0

sí, la función global no es necesaria en el segundo ejemplo. mi atención se centró más en el patrón de fábrica y no en el patrón de singleton :) – BabelFish

+0

Sí, después de leer su operación nuevamente, me di cuenta de que estaba hablando de fábrica en su lugar. mi error. Quizás alguien lo encuentre útil sin embargo. = P – prolink007

+1

Prefiero: 'example & example :: getExampleObject() {static example theInstance; devolver la instancia; } 'De esta forma no tendrá que preocuparse por los punteros nulos – Marlon

0

Las funciones gratuitas están bien en C++ e iría con esa ruta.

Poco relacionado: ¿por qué devuelve un puntero inteligente compartido de una fábrica? ¿La propiedad del objeto recién creado siempre va a ser compartida?

+0

en el código actual, sí, se comparte. :) perdón por la confusion – BabelFish

1

Todavía recomiendo poner las funciones en una clase (e incluso hacerlas virtuales). Es muy bueno poder reemplazar su fábrica por cualquier cantidad de razones, y hacer las cosas de esa manera lo hará mucho más fácil.

En la biblioteca estándar, las funciones de fábrica existen porque la expansión de la plantilla de función puede basarse en los tipos de argumentos, pero hasta C++ 17 no puede haber clases de plantilla que crean instancias de la clase basadas en los tipos alimentado al constructor. De modo que esas funciones de fábrica se consideran más como constructoras no miembros que como una fábrica. Siempre devuelven una instancia de un tipo particular, por ejemplo.

En una fábrica 'verdadera', la fábrica puede devolver cualquier tipo que implemente la interfaz especificada o se deriva del tipo especificado. Las fábricas verdaderas siempre devuelven punteros o (en casos excepcionales) referencias, pero no instancias reales.

Cuestiones relacionadas