Eu criei duas classes abstratas Subject e Observer que definem uma interface padrão clássica do Observer. Derivei deles para implementar o padrão Observer. Um observador pode ficar assim:
void MyClass::Update(Subject *subject)
{
if(subject == myService_)
{
DoSomething();
}
else if(subject == myOtherService_)
{
DoSomethingElse();
}
}
Isso é bom e me diz quem mudou alguma coisa. No entanto, isso não me diz o que mudou. Às vezes, está tudo bem, porque vou consultar o assunto para obter os dados mais recentes, mas outras vezes preciso saber o que exatamente mudou no assunto. Percebo em Java que eles têm um método notifyObservers () e um método notifyObservers (Object arg) para presumivelmente especificar detalhes sobre o que foi alterado.
No meu caso, preciso saber se uma das duas ações diferentes ocorreu sobre o assunto e, se for uma ação específica, saber um número inteiro relacionado a essa ação.
Então, minhas perguntas são:
- qual é a maneira C ++ de passar um argumento genérico (como Java faz)?
- O Observer é o melhor padrão? Talvez algum tipo de sistema de eventos?
ATUALIZAR
Eu encontrei este artigo que fala sobre a modelagem do padrão Observer: Implementando um padrão Subject / Observer com modelos . Isso me fez pensar se você poderia modelar um argumento.
Eu encontrei essa pergunta de estouro de pilha que fala sobre a modelagem do argumento: Padrão de Observer de assunto baseado em modelo - devo usar static_cast ou dynamic_cast . No entanto, o OP parece ter um problema que ninguém respondeu.
A outra coisa que eu poderia fazer é alterar o método Update para obter um objeto EventArg como em:
void MyClass::Update(Subject *subject, EventArg arg)
{
...
E, em seguida, crie subclasses do EventArg para dados de argumentos específicos e, em seguida, suponho que seja convertido de volta para a subclasse específica dentro do método de atualização.
ATUALIZAÇÃO 2
Também foi encontrado um artigo, Ao criar uma estrutura c ++ assíncrona baseada em mensagens; parte 2, que discute como o Assunto comunica detalhes sobre o que mudou.
Agora estou pensando seriamente em usar o Boost.Signals . Usar meu próprio padrão de observador fazia sentido quando era simples, mas modelar o tipo e o argumento está começando a ficar complicado. E talvez eu precise da segurança do thread do Boost.Signals2.
ATUALIZAÇÃO 3
Também encontrei alguns artigos interessantes sobre o padrão de observadores:
Generalizing Observer por Herb Sutter
Implementando o Padrão Observador em C ++ - Parte 1
Experiências de implementação do padrão de design do observador (parte 2)
Experiências de implementação do padrão de design do observador (parte 3)
No entanto, mudei minha implementação para usar o Boost.Signals que, embora possivelmente esteja um pouco inchado para os meus propósitos, está funcionando com êxito. E provavelmente quaisquer preocupações de inchaço ou velocidade são irrelevantes.