[Design mode] observer)

Source: Internet
Author: User

The observer mode defines one-to-multiple dependencies between objects. When the State of an object changes, all objects dependent on it will be automatically notified and updated.

Define a one-to-define dependency between objects so that one object changes state, all its dependents are notified and updated automatically.

In OO software design, a very important principle isReducing the coupling relationship between objects,The object state must be consistent.

The observer mode has two roles: Subject and observer. The relationship between the two is that one subject applies to multiple observers. When the status of the subject changes, you must notify the observer.

There are two ways to transmit information between them: Push and pull. The Push method is subject to push the changed data to the observer; the pull method means that the subject uses the least information to tell the observer that it needs to be updated. The obserer obtains (get) Subject data based on its own data requirements,

If the relationship between push and pull is complex, you can introduce a class specifically responsible for controlling changes-changemanager. Therefore, the MVC model is widely used. In fact, the MVC model uses at least two design patterns, one being the observer model, and the control class being the Mediator Model ).

The following code is the sample given by design patterns:

Defines an observer list, as well as the attach and detach functions of observer subscribe and unsubscribe, And the notify y function that sends notifications.

Here, subject is not defined as an abstract class equivalent to the Java interface, because C ++ supports multi-inheritance.

Subject. h

#ifndef _HEADER_SUBJECT_#define _HEADER_SUBJECT_#include <list>using namespace std;class Observer;class Subject {public:    virtual ~Subject();    virtual void Attach(Observer*);    virtual void Detach(Observer*);    virtual void Notify();protected:    Subject();private:    list<Observer*> _observers;};#endif // _HEADER_SUBJECT_


Subject. cpp

#include "subject.h"#include "observer.h"Subject::Subject() {}void Subject::Attach(Observer* o) {    _observers.push_front(o);}void Subject::Detach(Observer* o) {    _observers.remove(o);}void Subject::Notify() {    for (list<Observer*>::iterator it = _observers.begin(); it != _observers.end(); ++it) {        (*it)->Update(this);    }}Subject::~Subject() {    for (list<Observer*>::iterator it = _observers.begin(); it != _observers.end(); ++it) {        delete *it;    }}


The observer class is relatively simple, but the observer is a pure virtual class that defines only the UPDATE function that must be implemented by all subclasses.

Observer. h

#ifndef _HEADER_OBSERVER_#define _HEADER_OBSERVER_class Subject;class Observer {public:    virtual ~Observer() { }    virtual void Update(Subject* theChangedSubject) = 0;protected:    Observer() { }};#endif // _HEADER_OBSERVER_


Next we need to define the subject and observer instance classes. In this example, we use a clock class as the subject subclass.

Clocktimer. h

#ifndef _HEADER_CLOCK_TIMER_#define _HEADER_CLOCK_TIMER_#include "subject.h"class ClockTimer : public Subject {public:    ClockTimer();    virtual int GetHour();    virtual int GetMinute();    virtual int GetSecond();    void Tick();private:    int _hour;    int _minute;    int _second;};#endif


Clocktimer. cpp

#include "clocktimer.h"ClockTimer::ClockTimer() {}int ClockTimer::GetHour() {    return _hour;}int ClockTimer::GetMinute() {    return _minute;}int ClockTimer::GetSecond() {    return _second;}void ClockTimer::Tick() {    // update internal time-keeping state    // ...    _hour++;    _minute++;    _second++;    Notify();}


Then define the observer instance class

Digitalclock. h

#ifndef _HEADER_DIGITAL_CLOCK_#define _HEADER_DIGITAL_CLOCK_#include "widget.h"#include "observer.h"class ClockTimer;class DigitalClock : public Widget, public Observer {public:    DigitalClock(ClockTimer*);    virtual ~DigitalClock();    virtual void Update(Subject*);    virtual void Draw();private:    ClockTimer* _subject;};#endif


Digitalclock. cpp

#include "digitalclock.h"#include "clocktimer.h"#include <iostream>DigitalClock::DigitalClock(ClockTimer* s)    : _subject(s) {    _subject->Attach(this);}DigitalClock::~DigitalClock() {    _subject->Detach(this);}void DigitalClock::Update(Subject* theChangedSubject) {    if (_subject == theChangedSubject) {        Draw();    }}void DigitalClock::Draw() {    int hour = _subject->GetHour();    int minute = _subject->GetMinute();    std::cout << "hour: " << hour << "\n" << "minute: " << minute << std::endl;}


Main. cpp

#include "clocktimer.h"#include "digitalclock.h"int main(int argc, char** argv) {    ClockTimer* timer = new ClockTimer;    DigitalClock* digitalClock = new DigitalClock(timer);    timer->Tick();    timer->Tick();    timer->Tick();    return 0;}


Widget. h

#ifndef _HEADER_WIDGET_#define _HEADER_WIDGET_class Widget {public:    virtual ~Widget() { }    virtual void Draw() = 0;protected:    Widget() { }};#endif


Java provides ready-made observer interfaces and observable abstract classes to implement the observer mode.

However, because Java cannot inherit enough, the observable design is somewhat flawed. For details, see the Observer Pattern chapter in head first design patterns.

Because observable is a class, the subclass inherited from other classes cannot reuse the observable class.

If you define observable as an interface, you must rewrite the registration code to cancel registration and send notifications each time you implement the subject class.

Is this a drawback that Java does not support multi-inheritance?


PS: I haven't moved C ++ for nearly a year. It's really a little tricky...


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.