2011-02-12 23 views
5

Hola.
Después de leer here sobre el patrón Localizador de servicios, me hizo pensar si una clase con solo miembros estáticos realmente es el camino a seguir, o si un interace normal de tipo c no sería más apropiado. Veo gente lanzando la palabra clave class todo el tiempo cuando ni siquiera la necesitan.
Ejemplo con los miembros estáticos de clase tomada de la página enlazada:Clase de miembros estáticos vs. interfaz normal tipo c

class Locator 
{ 
public: 
    static IAudio* GetAudio() { return service_; } 

    static void Register(IAudio* service) 
    { 
     service_ = service; 
    } 

private: 
    static IAudio* service_; 
}; 

Aquí está una manera uno puede hacerlo también:

// in .h 
namespace Locator{ 
    IAudio* GetAudio(); 
    void Register(IAudio* service); 
} 

// in .cpp 
namespace Locator{ 
    namespace { 
     IAudio* service_; 
    } 

    IAudio* GetAudio() { 
     return service_; 
    } 
    void Register(IAudio* service) { 
     service_ = service; 
    } 
} 

Ambos ejemplos se pueden llamar exactamente de la misma manera con Locator::GetAudio() y Locator::Register(...). ¿Alguno de los anteriores es superior al otro? ¿Son lo mismo? ¿Hay quizás mejores formas de lograr esto? ¿O se trata solo de preferencias personales? Gracias por cualquier ayuda. :)

+0

Este es un patrón terrible. No tomaría el consejo de ningún sitio que recomiende variables globales como esta. – Puppy

+0

@Xeo: la verdadera pregunta: ¿por qué utilizar un estado global cuando podría proporcionar métodos regulares con datos por instancia? –

+0

@Matthieu: Entonces tendría que registrar la interfaz de audio en cada instancia de ubicación. ¿O quiso decir por qué uno necesitaría tal localizador en primer lugar? – Xeo

Respuesta

3

Su propuesta con espacios de nombres tiene una ligera debilidad en el mantenimiento: si necesita cambiar la interfaz por alguna razón, debe recordar cambiar tanto la interfaz (.h) como la implementación (.cpp), o una discrepancia no ser detectado hasta el tiempo de enlace. Si usa un class, el compilador puede detectar un error como una cantidad de parámetros que no coinciden.

Por otro lado, desde la implementación (service_) en su caso, sólo aparece en el archivo .cpp, es posible que pueda cambiar la aplicación privada del localizador sin forzar una recompilación de código que depende del localizador. (Los patrones comunes basados ​​en clases pueden proporcionar esta misma encapsulación.)

Estas son diferencias bastante menores. Un espacio de nombre público que contiene funciones es casi exactamente el mismo que una clase con funciones de miembro estáticas.

+0

Dado que el espacio de nombres para las funciones no es anónimo, supongo que se refiere al espacio de nombres para la variable (s)? – Xeo

+0

Lo siento, quise decir el espacio de nombres público 'Locator'. Se corrigió la respuesta. –

0

una buena razón para usar interfaces de clase es la coherencia.

a menudo, habrá una implementación de apoyo o uso de subclase de los datos compartidos en la clase Locator. por lo tanto, es preferible (para muchas personas) utilizar un enfoque en su base de código, en lugar de combinar espacios de nombres y clases para sus datos estáticos (ya que algunas implementaciones pueden extender o especializar el servicio).

A muchas personas no les gusta tratar con datos estáticos. algunos problemas de los ejemplos anteriores son: seguridad de la secuencia, propiedad y vida útil de los datos. los datos y las implementaciones pueden ser más fáciles de mantener si están restringidos a un alcance de clase (en lugar de un alcance de archivo). estos problemas aumentan a medida que crece la complejidad del programa: el ejemplo que ha publicado es muy simple.

las etiquetas/alias de espacio de nombre son más difíciles de transferir (en comparación con los tipos/typedefs/parámetros de plantilla). esto es útil si sus interfaces son similares y está usando una buena cantidad de programación genérica, o si simplemente desea implementar pruebas.

Cuestiones relacionadas