Stworzyłem dwie abstrakcyjne klasy Subject i Observer, które definiują klasyczny interfejs wzorców Observer. Czerpię z nich implementację wzorca Observer. Obserwator może wyglądać następująco:
void MyClass::Update(Subject *subject)
{
if(subject == myService_)
{
DoSomething();
}
else if(subject == myOtherService_)
{
DoSomethingElse();
}
}
To dobrze i mówi mi, kto coś zmienił. Jednak nie mówi mi, co się zmieniło. Czasami jest to w porządku, ponieważ po prostu zapytam podmiot o najnowsze dane, ale innym razem muszę wiedzieć, co dokładnie zmieniło się w temacie. Zauważyłem w Javie, że mają zarówno metodę replaceObservers (), jak i metodę noticeObservers (Object arg) , aby przypuszczalnie określać szczegóły zmian.
W moim przypadku muszę wiedzieć, czy jedno z kilku różnych działań miało miejsce w tym temacie, a jeśli jest to określone działanie, znać liczbę całkowitą związaną z tym działaniem.
Więc moje pytania to:
- jaki jest sposób C ++, aby przekazać ogólny argument (tak jak Java)?
- Czy Observer jest nawet najlepszym wzorem? Może jakiś system wydarzeń?
AKTUALIZACJA
Znalazłem ten artykuł, który mówi o szablonowaniu wzorca Observer: Implementowanie wzorca Temat / Obserwator za pomocą szablonów . To sprawiło, że zastanawiałem się, czy możesz szablonować argument.
Znalazłem pytanie o przepełnienie stosu, które mówi o szablonowaniu argumentu: Wzorzec obserwatora oparty na szablonie - czy powinienem użyć static_cast lub dynamic_cast . Wydaje się jednak, że PO ma problem, na który nikt nie odpowiedział.
Inną rzeczą, którą mogłem zrobić, to zmienić metodę Update, aby pobierała obiekt EventArg jak w:
void MyClass::Update(Subject *subject, EventArg arg)
{
...
A następnie utwórz podklasy EventArg dla konkretnych danych argumentów, a następnie przypuszczam, że wrzuciłem ją z powrotem do konkretnej podklasy w ramach metody aktualizacji.
AKTUALIZACJA 2
Znalazłem także artykuł na temat tworzenia asynchronicznej struktury c ++ opartej na komunikatach; część 2 omawiającej mające Temat komunikować szczegóły dotyczące tego, co zmieniło.
Teraz poważnie rozważam użycie Boost.Signals . Używanie własnego wzorca obserwatora miało sens, gdy było proste, ale szablonowanie typu i argument zaczyna się komplikować. I może potrzebuję bezpieczeństwa wątku Boost.Signals2.
AKTUALIZACJA 3
Znalazłem też kilka interesujących artykułów na temat wzorca obserwatora:
Generalizing Observer autorstwa Herb Sutter
Implementowanie wzorca obserwatora w C ++ - część 1
Doświadczenia związane z wdrażaniem wzorca projektowego obserwatora (część 2)
Doświadczenia związane z wdrażaniem wzorca projektowego obserwatora (część 3)
Jednak zmieniłem moją implementację na używanie Boost.Signals, które, choć być może nieco rozdęte dla moich celów, z powodzeniem działa. I prawdopodobnie wszelkie obawy o wzdęcie lub prędkość są nieistotne.