Avatar billede irsild Nybegynder
15. april 2001 - 22:13 Der er 1 kommentar og
1 løsning

ObserverPattern

Er der nogen der ved hvordan man realiserer Observerpattern i C++.
Avatar billede pstric Nybegynder
15. april 2001 - 23:05 #1
I \"Design Patterns\" er det implementeret således:

    class Subject;
   
    class Observer {
    public:
        virtual ~ Observer();
        virtual void Update(Subject* theChangedSubject) = 0;
    protected:
        Observer();
    };

    class Subject {
    public:
        virtual ~Subject();
   
        virtual void Attach(Observer*);
        virtual void Detach(Observer*);
        virtual void Notify();
    protected:
        Subject();
    private:
        List<Observer*> *_observers;
    };
   
    void Subject::Attach (Observer* o) {
        _observers->Append(o);
    }
   
    void Subject::Detach (Observer* o) {
        _observers->Remove(o);
    }
   
    void Subject::Notify () {
        ListIterator<Observer*> i(_observers);
   
        for (i.First(); !i.IsDone(); i.Next()) {
            i.CurrentItem()->Update(this);
        }
    }

Avatar billede pstric Nybegynder
15. april 2001 - 23:10 #2
Det var vist for lidt, du må nok hellere få lidt mere forklaring med:

An abstract class defines the Observer interface:

    class Subject;
   
    class Observer {
    public:
        virtual ~ Observer();
        virtual void Update(Subject* theChangedSubject) = 0;
    protected:
        Observer();
    };

This implementation supports multiple subjects for each observer. The subject passed to the Update operation lets the observer determine which subject changed when it observes more than one.

Similarly, an abstract class defines the Subject interface:

    class Subject {
    public:
        virtual ~Subject();
   
        virtual void Attach(Observer*);
        virtual void Detach(Observer*);
        virtual void Notify();
    protected:
        Subject();
    private:
        List<Observer*> *_observers;
    };
   
    void Subject::Attach (Observer* o) {
        _observers->Append(o);
    }
   
    void Subject::Detach (Observer* o) {
        _observers->Remove(o);
    }
   
    void Subject::Notify () {
        ListIterator<Observer*> i(_observers);
   
        for (i.First(); !i.IsDone(); i.Next()) {
            i.CurrentItem()->Update(this);
        }
    }

ClockTimer is a concrete subject for storing and maintaining the time of day. It notifies its observers every second. ClockTimer provides the interface for retrieving individual time units such as the hour, minute, and second.

    class ClockTimer : public Subject {
    public:
        ClockTimer();
   
        virtual int GetHour();
        virtual int GetMinute();
        virtual int GetSecond();
   
        void Tick();
    };

The Tick operation gets called by an internal timer at regular intervals to provide an accurate time base. Tick updates the ClockTimer\'s internal state and calls Notify to inform observers of the change:

    void ClockTimer::Tick () {
        // update internal time-keeping state
        // ...
        Notify();
    }

Now we can define a class DigitalClock that displays the time. It inherits its graphical functionality from a Widget class provided by a user interface toolkit. The Observer interface is mixed into the DigitalClock interface by inheriting from Observer.

    class DigitalClock: public Widget, public Observer {
    public:
        DigitalClock(ClockTimer*);
        virtual ~DigitalClock();
   
        virtual void Update(Subject*);
            // overrides Observer operation
   
        virtual void Draw();
            // overrides Widget operation;
            // defines how to draw the digital clock
    private:
        ClockTimer* _subject;
    };
   
    DigitalClock::DigitalClock (ClockTimer* s) {
        _subject = s;
        _subject->Attach(this);
    }
   
    DigitalClock:: DigitalClock () {
        _subject->Detach(this);
    }

Before the Update operation draws the clock face, it checks to make sure the notifying subject is the clock\'s subject:

    void DigitalClock::Update (Subject* theChangedSubject) {
        if (theChangedSubject == _subject) {
            Draw();
        }
    }
   
    void DigitalClock::Draw () {
        // get the new values from the subject
   
        int hour = _subject->GetHour();
        int minute = _subject->GetMinute();
        // etc.
   
        // draw the digital clock
    }

An AnalogClock class can be defined in the same way.

    class AnalogClock : public Widget, public Observer {
    public:
        AnalogClock(ClockTimer*);
        virtual void Update(Subject*);
        virtual void Draw();
        // ...
    };

The following code creates an AnalogClock and a DigitalClock that always show the same time:

    ClockTimer* timer = new ClockTimer;
    AnalogClock* analogClock = new AnalogClock(timer);
    DigitalClock* digitalClock = new DigitalClock(timer);

Whenever the timer ticks, the two clocks will be updated and will redisplay themselves appropriately.

Kilde: Design Patterns CD
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester