He creado dos clases abstractas de sujeto y observador que definen una interfaz de patrón de observador clásica. Derivo de ellos para implementar el patrón Observador. Un observador podría verse así:
void MyClass::Update(Subject *subject)
{
if(subject == myService_)
{
DoSomething();
}
else if(subject == myOtherService_)
{
DoSomethingElse();
}
}
Esto está bien y me dice quién cambió algo. Sin embargo, no me dice qué cambió. A veces esto está bien porque solo voy a consultar el Asunto para obtener los datos más recientes, pero otras veces necesito saber qué cambió exactamente en el Asunto. Noté que en Java tienen un método notifyObservers () y un método notifyObservers (Object arg) para presumiblemente especificar detalles sobre lo que cambió.
En mi caso, necesito saber si ocurrió una de un par de acciones diferentes sobre el tema y, si se trata de una acción en particular, conocer un número entero relacionado con esa acción.
Entonces mis preguntas son:
- ¿Cuál es la forma en C ++ de pasar un argumento genérico (como lo hace Java)?
- ¿Observer es incluso el mejor patrón? ¿Quizás algún tipo de sistema de eventos?
ACTUALIZAR
Encontré este artículo que habla sobre la plantilla del patrón Observador: Implementar un patrón Sujeto / Observador con plantillas . Esto me hizo preguntarme si podrías modelar un argumento.
Encontré esta pregunta de desbordamiento de pila que habla sobre la plantilla del argumento: Patrón de Observador de Sujetos basado en plantillas : ¿Debo usar static_cast o dynamic_cast ? Sin embargo, el OP parece tener un problema que nadie ha respondido.
La otra cosa que podría hacer es cambiar el método de actualización para tomar un objeto EventArg como en:
void MyClass::Update(Subject *subject, EventArg arg)
{
...
Y luego cree subclases de EventArg para datos de argumentos específicos, y luego supongo que lo devuelve a la subclase específica dentro del método de actualización.
ACTUALIZACIÓN 2
También encontré un artículo, Sobre la creación de un marco de trabajo asincrónico basado en c ++; parte 2, que trata de que el Sujeto comunique detalles sobre lo que cambió.
Ahora estoy considerando seriamente usar Boost.Signals . Usar mi propio patrón de observador tenía sentido cuando era simple, pero comenzar a complicar el tipo y el argumento. Y es posible que necesite la seguridad del hilo de Boost.Signals2.
ACTUALIZACIÓN 3
También encontré algunos artículos interesantes sobre el patrón de observación:
Observador generalizador por Herb Sutter
Implementación del patrón de observador en C ++ - Parte 1
Experiencias de implementación del patrón de diseño de observador (Parte 2)
Experiencias de implementación del patrón de diseño de observador (Parte 3)
Sin embargo, he cambiado mi implementación para usar Boost.Signals que, aunque posiblemente un poco hinchado para mis propósitos, funciona con éxito. Y probablemente cualquier preocupación de hinchazón o velocidad sea irrelevante.