梁越

c++设计模式-观察者模式

0 人看过

观察者模式

适用情况

比较常用的情况就是订阅和通知

例如qq群的通知,每个成员订阅该群,然后群里发送某个命令或者通知,该群的所有成员都可以收到,并作出自己的行动

优缺点

优点:符合开闭原则,无需修改就可以添加新的订阅者
缺点:订阅者的通知顺序时随机的

模式关键点

观察者需要两个抽象类
一个是发布者subject,需要实现添加订阅、删除订阅、通知的功能
另一个是订阅者observer,起码要实现一个响应功能update

代码实例

实例1

/*
 * 观察者模式
 * 情景:高数课,ABCD四位同学,A是好学生,去上课,B在寝室睡觉,C在网吧打游戏,D在学校外陪女友逛街
 * 他们约定,如果要点名了,A在QQ群里吼一声,他们立刻赶到教室去。
 * 采用观察者模式实现这个情景的应用。
 */

#include <iostream>
#include <string>
#include <list>

class Observer;

class Subject{
public:
    virtual ~Subject() {};
    virtual void registerObsvr(Observer* obsvr) = 0;
    virtual void removeObsvr(Observer* obsvr) = 0;
    virtual void notifyObsvrs(const std::string &msg) = 0;
};
class Observer {
public:
    virtual ~Observer() {};
    virtual void Update(const std::string &msg)= 0;
    virtual std::string getName() = 0;
protected:
    Observer(){};
};

// -------------------------------------------------
class QQGroup : public Subject {
public:
    QQGroup() { _observers = new std::list<Observer*>(); }
    void registerObsvr(Observer* obsvr);
    void removeObsvr(Observer* obsvr);
    void notifyObsvrs(const std::string &msg);
private:
    std::list<Observer*> *_observers;
};

void QQGroup::registerObsvr(Observer* obsvr) {
    _observers->push_back(obsvr);
}

void QQGroup::removeObsvr(Observer* obsvr) {
    if (_observers->size() > 0)
        _observers->remove(obsvr);
}
void QQGroup::notifyObsvrs( const std::string &msg) {
    std::cout << "群消息:" << msg << std::endl;
    std::list<Observer*>::iterator iter
        = _observers->begin();
    for ( ;iter != _observers->end(); iter++ ) {
        (*iter)->Update(msg);
    }
}

// ------------------------------------------------
class RoomMate : public Observer {
public:
    RoomMate(std::string name, std::string now ,std::string action)
    {
        _name = name;
        _action = action;
        _now = now;
    };
    void Update( const std::string &msg);
    std::string getName();
private:
    std::string _name;
    std::string _action;
    std::string _now;
};

std::string RoomMate::getName() {
    return _name;
}

void RoomMate::Update(const std::string &msg) {
    std::cout<< "This is " << _name << std::endl;
    if ( msg == "点名了" )
        std::cout << "Action: " << _action
        << std::endl << std::endl;
    else
        std::cout << "Go on:" << _now
        << std::endl << std::endl ;
}

//测试代码
int main()
{
    RoomMate* B = new RoomMate("B",
        "sleeping",
        "get dressed and run to classroom");
    RoomMate* C = new RoomMate("C",
        "playing games",
        "pay the fee and run to classroom");
    RoomMate* D = new RoomMate("D",
        "shopping with girl friend",
        "go back to school and be worried about girl friend's angry");

    QQGroup* qqgroup = new QQGroup();
    qqgroup->registerObsvr(B);
    qqgroup->registerObsvr(C);
    qqgroup->registerObsvr(D);

    qqgroup->notifyObsvrs("目前没点名");
    qqgroup->notifyObsvrs("点名了");

    system("Pause");
    return 0;
}

实例2

class IObserver {
 public:
  virtual ~IObserver(){};
  virtual void Update(const std::string &message_from_subject) = 0;
};

class ISubject {
 public:
  virtual ~ISubject(){};
  virtual void Attach(IObserver *observer) = 0;
  virtual void Detach(IObserver *observer) = 0;
  virtual void Notify() = 0;
};


class Subject : public ISubject {
 public:
  virtual ~Subject() {
    std::cout << "Goodbye, I was the Subject.\n";
  }

  void Attach(IObserver *observer) override {
    list_observer_.push_back(observer);
  }
  void Detach(IObserver *observer) override {
    list_observer_.remove(observer);
  }
  void Notify() override {
    std::list<IObserver *>::iterator iterator = list_observer_.begin();
    HowManyObserver();
    while (iterator != list_observer_.end()) {
      (*iterator)->Update(message_);
      ++iterator;
    }
  }

  void CreateMessage(std::string message = "Empty") {
    this->message_ = message;
    Notify();
  }
  void HowManyObserver() {
    std::cout << "There are " << list_observer_.size() << " observers in the list.\n";
  }

  void SomeBusinessLogic() {
    this->message_ = "change message message";
    Notify();
    std::cout << "I'm about to do some thing important\n";
  }

 private:
  std::list<IObserver *> list_observer_;
  std::string message_;
};

class Observer : public IObserver {
 public:
  Observer(Subject &subject) : subject_(subject) {
    this->subject_.Attach(this);
    std::cout << "Hi, I'm the Observer \"" << ++Observer::static_number_ << "\".\n";
    this->number_ = Observer::static_number_;
  }
  virtual ~Observer() {
    std::cout << "Goodbye, I was the Observer \"" << this->number_ << "\".\n";
  }

  void Update(const std::string &message_from_subject) override {
    message_from_subject_ = message_from_subject;
    PrintInfo();
  }
  void RemoveMeFromTheList() {
    subject_.Detach(this);
    std::cout << "Observer \"" << number_ << "\" removed from the list.\n";
  }
  void PrintInfo() {
    std::cout << "Observer \"" << this->number_ << "\": a new message is available --> " << this->message_from_subject_ << "\n";
  }

 private:
  std::string message_from_subject_;
  Subject &subject_;
  static int static_number_;
  int number_;
};

int Observer::static_number_ = 0;

void ClientCode() {
  Subject *subject = new Subject;
  Observer *observer1 = new Observer(*subject);
  Observer *observer2 = new Observer(*subject);
  Observer *observer3 = new Observer(*subject);
  Observer *observer4;
  Observer *observer5;

  subject->CreateMessage("Hello World! :D");
  observer3->RemoveMeFromTheList();

  subject->CreateMessage("The weather is hot today! :p");
  observer4 = new Observer(*subject);

  observer2->RemoveMeFromTheList();
  observer5 = new Observer(*subject);

  subject->CreateMessage("My new car is great! ;)");
  observer5->RemoveMeFromTheList();

  observer4->RemoveMeFromTheList();
  observer1->RemoveMeFromTheList();

  delete observer5;
  delete observer4;
  delete observer3;
  delete observer2;
  delete observer1;
  delete subject;
}

int main() {
  ClientCode();
  return 0;
}

输出结果

Hi, I'm the Observer "1".
Hi, I'm the Observer "2".
Hi, I'm the Observer "3".
There are 3 observers in the list.
Observer "1": a new message is available --> Hello World! :D
Observer "2": a new message is available --> Hello World! :D
Observer "3": a new message is available --> Hello World! :D
Observer "3" removed from the list.
There are 2 observers in the list.
Observer "1": a new message is available --> The weather is hot today! :p
Observer "2": a new message is available --> The weather is hot today! :p
Hi, I'm the Observer "4".
Observer "2" removed from the list.
Hi, I'm the Observer "5".
There are 3 observers in the list.
Observer "1": a new message is available --> My new car is great! ;)
Observer "4": a new message is available --> My new car is great! ;)
Observer "5": a new message is available --> My new car is great! ;)
Observer "5" removed from the list.
Observer "4" removed from the list.
Observer "1" removed from the list.
Goodbye, I was the Observer "5".
Goodbye, I was the Observer "4".
Goodbye, I was the Observer "3".
Goodbye, I was the Observer "2".
Goodbye, I was the Observer "1".
Goodbye, I was the Subject.

参考链接