2010-01-26 14 views
6

Recientemente he estado escribiendo código similar al siguiente:clase abstracta - ocultando aplicación en la práctica C++

messagehandler.h:

#include "message.h" 
class MessageHandler { 
public: 
    virtual ~MessageHandler() {} 
    virtual void HandleMessage(Message *msg) = 0: 
}; 

persistmessagehandler.h:

MessageHandler *CreatePersistMessageHandler(); 

persistmessagehandler. cpp:

#include "messagehandler.h" 
#include "persist.h" 

class PersistMessageHandler : public MessageHandler { 
private: 
    PersistHandle ph; 
    size_t count; 
    InternalCheck(); 
public: 
    PersistMessageHandler(int someParam); 
    virtual ~PersistMessageHandler(); 
    virtual void HandleMessage(Message *msg): 
}; 
PersistMessageHandler::PersistMessageHandler(int someParam) 
{ 
    ph.Initialize(); 
} 
... rest of implementation. 

MessageHandler *CreatePersistMessageHandler(int someParam) 
{ 
    return new PersistMessageHandler(someParam); 
} 

El razonamiento aquí es ocultar PersistMessageHandler. Los clientes no necesitan incluir un encabezado para la clase PersistMessageHandler, con todas las inclusiones y tipos que la implementación pueda necesitar, y para separar más limpiamente la interfaz y la implementación. . Siempre se asignará dinámicamente de todos modos,

Todos los usuarios de PersistMessageHandler simplemente llamarán a CreatePersistMessageHandler (..); directa o indirectamente obtener uno de una fábrica.

Pero. No he visto este enfoque usado mucho en otros lugares. Es la buena práctica anterior? ¿Hay otras/mejores alternativas para casos simples?

+0

¿Por qué alguien podría abreviar "Mensaje" a "Messge"? ¿Es un error tipográfico? – unwind

+0

¡Buena pregunta! Hago esto todo el tiempo y siempre me he preguntado si era kosher.Excepto que mi declaración es: 'std :: auto_ptr CreatePersistMessageHandler();' –

+0

Vea también http://stackoverflow.com/questions/825018/pimpl-idiom-vs-pure-virtual-class-interface – Frank

Respuesta

6

Siempre tiene que esconderse tanto como sea posible. A su manera (poner clases de implementación en .cpp) es una forma común de hacer esto en C++.

1

Claro, parece que a form of the factory pattern. Los usuarios de la fábrica no están interesados ​​en sus detalles internos, solo se preocupan por las cosas que crea.

2

Esta es una buena manera de ocultar los detalles de implementación de sus clientes. Si está trabajando en Windows, también podría considerar usar una interfaz __ en lugar de una clase base abstracta.

Una interfaz es una extensión del compilador de MSVC que se parece a una clase base abstracta, pero tiene reglas diferentes para la creación y la destrucción que una clase normal de C++. Es la forma estándar de trabajar en Windows, por lo que hay instalaciones compatibles con el sistema para trabajar con objetos fuera de proceso y para usarlos en el código .NET.

0

Reducir al mínimo la dependencia de los detalles de implementación ciertamente es grande, y ocultar cosas más allá de la clase base abstracta (ABC, también conocido como interfaz) es una solución buena e idiomática.

La desventaja de utilizar ABC es que se pierde la semántica de valor de su clase que podría ser o no aceptable/deseable.

Una técnica que también oculta los detalles de implementación sin este inconveniente es Pimpl. Supongo que deberías estar al tanto.

Prefiero ABC en la mayoría de los casos.

+0

@CraigMcQueen error ortográfico , debe ser ABC (clase base abstracta). ¡Gracias! –

Cuestiones relacionadas