Pracuję z biblioteką zewnętrzną i muszę utworzyć wzorzec obserwatora, w którym obserwatorzy pochodzą z obiektu należącego do biblioteki. Nie chcę zmieniać klasy bazowej z biblioteki, a jednocześnie muszę używać listy referencji/wskaźników do tej niezmiennej klasy bazowej. Ponadto biblioteka tworzy listę obiektów, z których muszę przesiać te, które nadają się do obserwowania.Używanie RTTI z obiektami pochodzącymi z biblioteki zewnętrznej
Kod pisałem to z grubsza odpowiednik tego:
#include <iostream>
#include <vector>
#include <memory>
// This class is from an external library which I don't want to chagne
class BaseFromLibrary {
public:
virtual ~BaseFromLibrary() {}
};
class BaseOfObserver {
public:
void notify() { std::cout << "What-ho!\n"; };
};
class Observer : public BaseFromLibrary, public BaseOfObserver {};
class Subject {
public:
std::vector<std::shared_ptr<Observer>> observers;
void notifyObervers() {
for (auto &o : observers)
(*o).notify();
}
};
int main() {
// This list is constructed by the library and I cannot interfere with that
// process
std::vector<std::shared_ptr<BaseFromLibrary>> list{
std::make_shared<BaseFromLibrary>(), std::make_shared<Observer>()};
Subject s;
for (auto &e : list)
if (std::dynamic_pointer_cast<Observer>(e) != nullptr)
s.observers.push_back(std::dynamic_pointer_cast<Observer>(e));
s.notifyObervers();
}
Następnie używam BaseOfObserver
dodać „osobnik” świadomości do innych moich typów pochodnych. W ten sposób nie muszę powtarzać instrukcji if dla każdego konkretnego obserwatora, który chcę zaimplementować.
Wygląda na to, że działa dobrze, ale czy to błąd w projektowaniu? Czy istnieje lepszy sposób tworzenia listy obserwatorów bez mechanizmu RTTI i bez ingerencji w klasy biblioteki?
Jeśli dobrze Cię rozumiem, sugerujesz podział "listy" z mojego przykładu. Być może zapomniałem podkreślić, że jest to również coś, czego nie mogę zrobić. Biblioteka sama tworzy tę listę i nie chcę ingerować w ten proces. Spróbuję to edytować. Punkt zajęty wyciekiem pamięci. –