Si, ma se ci pensi bene la chiave di tutto è la funzione update(): è li che devi discriminare i vari tipi di subject che interessano all'observer, non da altre parti. Il resto è solo nebbia in val padana.Il tentativo fatto con setSubject in associazione a dynamic_cast, era per avere un metodo da reimplementare in base alle necessita' nelle classi concrete di observer, senza avere un sistema adatto al singolo caso specifico, spero di essermi spiegato questa volta.
Fermo restando l'ultimo codice che ti ho mostrato, è sufficiente modificare la update() in questo modo:
Ovviamente ogni observer avrà la sua update() con i suoi subjects da discriminare e i subjects la loro notify() per la loro lista di observers. E il tutto funziona con N observers e M subjects. Qui ho usato dynamic_cast<>, che comunque non è così lento da farti prendere sonnocodice:class DerObserverMoreSubject : public Observer { public: void update(Subject1* subject) override { auto sub = mSubjects.find(subject); // se il subject non è nel set non faccio niente. if (sub != m_Subjects.end()) { // i subjects interessati sono quelli che ho deciso di osservare auto ptr1 = dynamic_cast<DerSubject1*>(subject); if (ptr1 != nullptr) { // aggiorno l'observer con i dati di ptr2 } auto ptr2 = dynamic_cast<DerSubject2*>(subject); if (ptr2 != nullptr) { // aggiorno l'observer con i dati di ptr2 } auto ptr3 = dynamic_cast<DerSubject3*>(subject); if (ptr3 != nullptr) { // aggiorno l'observer con i dati di ptr3 } // altri subjects non previsti sono ignorati. } } };, perché è più comodo, meno laborioso e più sicuro di enum più funzione virtuale.
Oddio, se ci fosse un doppione dello stesso subject avresti due chiamate a update() di cui solo una ti serve per l'aggiornamento dell'observer, l'altra lo sovrascrive con gli stessi dati.Interessante std::set: tra l'altro toglie il pensiero di controllare l'unicita' del dato passato, qualora questo sia un requisito.

, perché è più comodo, meno laborioso e più sicuro di enum più funzione virtuale.
Rispondi quotando