Visualizzazione dei risultati da 1 a 10 su 13

Hybrid View

  1. #1
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Il dubbio principale e' se nelle classi derivate da Observer tengo come riferimento un dato membro di tipo Subject o DerSubject, cioe' quello che sara' il reale tipo di subject osservato: credo la seconda, anche se nell'esempio di codice sopra postato ho fatto il contrario.
    No, è la prima. Passando un puntatore a classe base perdi le informazioni su cosa sia la classe derivata, cosa che un puntatore a DerSubject richiede. Ricorda che un observer può osservare diversi subject (ragione per cui si passa un puntatore a subject in update() ), come un subject può avere diversi observer e non è possibile (in teoria) tenere traccia di tutte le possibili implementazioni.

    Inoltre, potrebbe mai essere necessario implementare un metodo setSubject nelle classi derivate da Observer per poter cambiare il Subject osservato?

    Lo vedo poco utile. Ogni volta che devi osservare un subject diverso devi andare di setSubject.
    Personalmente aggiungerei due metodi virtuali addSubject(Subject*) / removeSubject(Subject*) che mi consentano l'inserimento in un std::set<> delle varie istanze subject che voglio controllare in update().
    In codice:
    codice:
    class Subject;
    
    class Observer
    {
      public:
        virtual ~Observer(){};
        virtual void update(Subject*subject)=0;
        virtual void addSubject(Subject* sub)=0;
        virtual void removeSubject(Subject* sub)=0;
      protected:
        Observer(){};
    };
    
    class Subject
    {
      public:
        virtual ~Subject(){};
        virtual void attach(Observer*observer);
        virtual void detach(Observer*observer);
        virtual void notify();
      protected:
        Subject(){};
      private:
        std::set<Observer*>mObserverList;
    };
    
    
    class DerSubject: public Subject {};
    
    class ObserverTester: public Observer
    {
      public:
        ObserverTester(Subject* subject)
        {
                addSubject(subject);
        }; 
        
        void addSubject(Subject* sub) {
          sub=subject;
          sub->attach(this);
            mSubjects.insert(sub);
        }
    
        void removeSubject(Subject* sub) {
          sub->dettach(this); 
            mSubjects.remove(sub);
        }
        
        
        void update(Subject* subject) override
        {
          
          auto sub = mSubject.find(subject);
          if(sub != mSubjects.end())
          {
            std::cout<<"\nHello from observer "<<this;
            std::cout<<"\nI'm observing subject "<<sub;
          }
        };
      private:
        std::set<Subject*> mSubjects;
    };
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  2. #2
    Utente di HTML.it L'avatar di ing82
    Registrato dal
    Sep 2014
    Messaggi
    177
    Quote Originariamente inviata da shodan Visualizza il messaggio
    No, è la prima. Passando un puntatore a classe base perdi le informazioni su cosa sia la classe derivata, cosa che un puntatore a DerSubject richiede. Ricorda che un observer può osservare diversi subject (ragione per cui si passa un puntatore a subject in update() ), come un subject può avere diversi observer e non è possibile (in teoria) tenere traccia di tutte le possibili implementazioni.
    Ok. Non capisco allora come poter ricavare i dati che mi servono dai subject per poter aggiornare l'observer tramite il metodo update.

    Il caso reale che mi ha portato ad usare il design pattern observer è un oggetto che dipende da altri due, nel senso che se modifico uno dei due, o entrambi, l'oggetto 'indipendente' si deve aggiornare in automatico.

    Il design pattern observer mi sembrava adatto allo scopo.

    Avro' quindi due subject, che sono di due classi diverse, perchè rappresentano due cose diverse, in cui registrerò il mio observer (DerSubject1 e DerSubject2).

    Nell'observer, dovrò quindi tenere traccia di entrambi i subject osservati, che non varieranno di numero.

    Se nell'observer memorizzo i due subject come Subject, non riesco ad accedere 'direttamente' (bisogna fare cast) ai metodi implementati nella classe derivata, che sono quelli che permettono di ricavare i dati necessari all'aggiornamento dell'observer.

    Se li memorizzo come DerSubject1 e DerSubject2 riesco invece ad accedere direttamente ai metodi necessari a ricavare i dati necessari all'observer.

    Potrebbe sembrare esagerato usare il d.p. observer per una cosa del genere, in realtà gli stessi due subject potrebbero dover essere osservati, e quindi notificare eventuali modifiche, da un altro observer, 'concettualmente' diverso dal precedente (sarebbero quindi DerObserver1 e DerObserver2).

    Inoltre, la modifica di uno dei due subject, richiederebbe l'aggiornamento di altri tipi di observer, che non ho ancora implementato, ma che lo dovranno essere a breve, ecco il perchè del tentativo di ricorrere al d.p. observer.

  3. #3
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Quote Originariamente inviata da ing82 Visualizza il messaggio
    Avro' quindi due subject, che sono di due classi diverse, perchè rappresentano due cose diverse, in cui registrerò il mio observer (DerSubject1 e DerSubject2).
    Nell'observer, dovrò quindi tenere traccia di entrambi i subject osservati, che non varieranno di numero.
    Ok, i subject sono due. A questo punto il parametro della funzione update() serve solo a stabilire quale subject usare per aggiornare i dati dell'observer. A questo punto dovresti modificare update() così:
    codice:
          if(subject==mSubject1)
          {
            std::cout<<"\nHello from observer "<<this;
            std::cout<<"\nI'm observing subject "<<mSubject1;
            parametro1 = mSubject1->metodo1(); // esempio
          }
    
          if(subject==mSubject2)
          {
            std::cout<<"\nHello from observer "<<this;
            std::cout<<"\nI'm observing subject "<<mSubject2;
            parametro2 = mSubject2->metodo2(); // esempio
          }
    Inoltre non puoi passare nel costruttore (o altra funzione preposta) un generico Subject*. Devi passare proprio DerSubject1* e DerSubject2* se non vuoi perdita di informazioni.

    ...ecco il perchè del tentativo di ricorrere al d.p. observer.
    Beh, è il suo mestiere, no?
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  4. #4
    Utente di HTML.it L'avatar di ing82
    Registrato dal
    Sep 2014
    Messaggi
    177
    Quote Originariamente inviata da shodan Visualizza il messaggio
    A questo punto il parametro della funzione update() serve solo a stabilire quale subject usare per aggiornare i dati dell'observer.
    Ok, come pensavo.



    Quote Originariamente inviata da shodan Visualizza il messaggio
    Inoltre non puoi passare nel costruttore (o altra funzione preposta) un generico Subject*. Devi passare proprio DerSubject1* e DerSubject2* se non vuoi perdita di informazioni.
    e di conseguenza anche i due dati membro deputati a tenere il riferimento ai due osservati, saranno del tipo derivato, DerSubject1* e DerSubject2*...

    Grazie

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2026 vBulletin Solutions, Inc. All rights reserved.