Skip to main content
  1. Posts/

[设计模式] 观察者( Observer )模式学习笔记

Note: This article is available in Chinese only. 本文暂无英文版本。 View original

最近在学习node.js,里面讲到node.js的事件机制使用了观察者模式,因此来学习一下。

观察者模式的目的是定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

因此观察者模式又叫发布-订阅模式。

下面放一个简化之后的例子:

 1
 2    
 3    #include <iostream>
 4    #include <vector>
 5    #include <string>
 6    using namespace std;
 7    class Secretary;
 8    // 看股票的同事类(观察对象,观察者)
 9    class StockObserver
10    {
11    public:
12    	StockObserver(string strName, Secretary* strSub)
13    	{
14    		name = strName;
15    		sub = strSub;
16    	}
17     
18    	void Update();
19     
20    private:
21    	string name;
22    	Secretary* sub;我所理解的设计模式(C++实现)——观察者模式(Observer Pattern
23    };
24     
25    // 秘书类(主题对象,通知者)
26    class Secretary
27    {
28     
29    public:
30    	string action;
31    	void Add(StockObserver ob) { observers.push_back(ob); }
32    	void Remove(int addIndex)
33    	{
34    		if(addIndex >=0 && addIndex < observers.size())
35    		observers.erase(observers.begin() + addIndex);
36    	}
37    	void Notify()
38    	{
39    		vector<StockObserver>::iterator it;
40    		for (it=observers.begin(); it!=observers.end(); ++it)
41    		{
42    			(*it).Update();
43    		}
44    	}
45     
46    private:
47    	vector<StockObserver> observers;
48    };
49     
50     
51     
52     
53    void StockObserver::Update()
54    {
55    	cout << name << " : " << sub->action << ", begin to work" << endl;
56    }
57     
58    int main()
59    {
60    	// 创建通知者
61    	Secretary* p = new Secretary();
62     
63    	// 观察者
64    	StockObserver* s1 = new StockObserver("Lazy", p);
65    	StockObserver* s2 = new StockObserver("SnowFire", p);
66     
67    	// 加入通知队列
68    	p->Add(*s1);
69    	p->Add(*s2);
70     
71    	// 事件
72    	p->action = "The boss is coming...";
73     
74    	// 通知
75    	p->Notify();
76     
77    	// 动态删除
78    	p->Remove(0);
79    	
80    	p->Notify();
81     
82    	return 0;
83     
84    

update:怪不得觉得熟悉,原来Qt的信号槽机制Signals_and_slots 就是使用了观察者模式。

参考资料:

观察者模式-菜鸟教程

我所理解的设计模式(C++实现)——观察者模式(Observer Pattern)

Related

[C++11] promise && future leanrning notes

用人话就是,主线程传给附属线程一个promise Object,然后主线程想要获取附属线程set给promise Object的值(也就是该线程返回的某个结果),需要通过主线程中的promise object 得到对应的future object(每个promise 对应一个 future),然后调用future 的get方法。如果附属线程没有执行作为参数传入的promise的set方法去返回结果,那么程序就会block住。

把二进制文件按字节读到vector中

·1 min
1 std::vector<unsigned char> readFromFile1(const char* filePath) { 2 FILE* file = fopen(filePath, "rb"); 3 std::vector<unsigned char> result; 4 if (file == nullptr) { 5 return result; 6 } 7 8 // 获取文件大小,尽量一次读完 9 size_t fileSize = getFileSize(file); 10 if (fileSize != 0) { 11 result.resize(fileSize); 12 size_t n = fread(&result[0], 1, fileSize, file); 13 assert(n <= fileSize); 14 if (n != fileSize) { 15 result.resize(n); 16 } 17 } 18 19 // 在读取过程当中,有可能文件大小有变化,再尝试读取 20 const size_t read_len = 1024; 21 char buf[read_len]; 22 for (;;) { 23 size_t n = fread(buf, 1, read_len, file); 24 result.insert(result.end(), buf, buf + n); 25 if (n < read_len) { 26 break; 27 } 28 } 29 fclose(file); 30 return result; 31 } 另外一种C++风格,但是性能较差的方法: