现在假设一种情形:一个人(person)要去看公告(Note)的内容,需要Note去setNews(string);设置发布的内容,那么写下来就是一个Note类和person类,两个类根据需求写一些代码,写下来就是下面这样。。
#include <stdlib.h>
#include <iostream>
#include <string>
using namespace std;
class Note {
public:
void setNews(string a) {
news = a;
cout << a << endl;
};
string getNews(void) { return news; };
private:
string news = "null";
};
class Person {
public:
// void setNote(Note *note) { mNote = note; }
Person(Note *nt) : mNote(nt) {}
void printNews() { cout << getNews() << endl; }
private:
Note *mNote;
string getNews() { return mNote->getNews(); }
};
int main() {
Note* noteA = new Note();
noteA->setNews("国庆放7天");
Person *personA = new Person(noteA);
personA->printNews();
}
那么这是单独的一对一的情况,那么如果需要多对多呢?比如5个互相不认识的人,5个不同的公告版。硬写,就是先写5个person类,5个Note类,在互相组合。这样的代码和面向过程没有区别,难以维护,耦合度极高。不便于维护。自然可以想到把Note抽象出来,把Person抽象出来。让两个基类去耦合。
先把消息抽象出来成Msg类,用phone类去继承Msg // 即模拟手机得到消息
class Msg {
public:
void setNews(string a) {
news = a;
cout << a << endl;
};
string getNews(void) { return news; };
private:
string news = "null";
};
class phone : public Msg {
public:
void setNews(string a) { setNews(a); }
void showNews() { cout << getNews() << endl; }
};
在把读消息的人抽象成reader类,用student去继承reader类。 // 模拟学生去看消息
class Reader {
public:
Reader(Msg *nt) : mNote(nt) {}
virtual void printNews() = 0;
string getNews() { return mNote->getNews(); }
private:
Msg *mNote;
};
class student : public Reader {
public:
student(string name, Msg *mg) : Reader(mg){
mName = name;
};
private:
virtual void printNews() {
cout << "我是" << mName << ": " ;
cout << "读到了" << getNews() << endl;
};
string mName;
};
然后客户端调用: 手机上有消息“国庆放7天”, 小明读到了:“国庆放7天”。
int main() {
Msg *msg = new phone("国庆放7天");
Reader* mReader = new student("小明",msg);
mReader->printNews();
}
以上就是所谓的观察者模式:就是抽象的Reader类去读取抽象的Msg类,这样。N个信息来源,比如手机,平板,电视。。。以及N个读信息的人,比如学生,医生,警察。都可以任意的组合,需要哪个人(比如student)和信息来源(比如iphone)就去初始化这两个类,并且通过统一的接口(Reader->printfNews())去模拟观察者读到消息。。
总之,观察者模式适用于N个对象和N个对象之间的交互。把需要耦合的部分放在了各自的基类里面。