Design Patterns 5 - 观察者模式 Observer
Design Patterns 5 - 观察者模式 Observer
https://www.bilibili.com/video/BV1kW411P7KS?p=5
都是亲手敲出来的,转载请注明出处,谢谢。
https://www.bilibili.com/video/BV1kW411P7KS?p=5 //FileSpliter.cpp class FileSpliter{ string m_filePath; int m_fileNumber; public: FileSpliter(const string &filePath, int fileNumber): m_filePath(filePath), m_fileNumber(fileNumber){ } void split(){ //1. 读取文件 //2. 分批次想小文件写入 for (int i = 0; i < m_fileNumber; i++){ //... } } }; //MainForm.cpp class MainForm : public Form{ Text * textFilePath; Text * textFileNumber; public: void Button1_Click(){ string filePath = textFilePath->getText(); int number = atoi(textFileNumber->getText.c_str()); FileSpliter spliter(filePath, number); spliter.split(); } }; //FileSpliter1.cpp //有什么问题? //违背依赖倒置原则 class FileSpliter{ string m_filePath; int m_fileNumber; ProgressBar *m_progressBar; //编译时依赖,实现细节 public: FileSpliter(const string &filePath, int fileNumber, ProgressBar *progressBar): m_filePath(filePath), m_fileNumber(fileNumber), m_progressBar(progressBar){ } void split(){ //1. 读取文件 //2. 分批次想小文件写入 for (int i = 0; i < m_fileNumber; i++){ //... if(NULL != m_progressBar{ m_progressBar->setValue((i + 1) / m_fileNumber); //更新进度条 } } } }; //MainForm1.cpp //需求:增加进度条 class MainForm : public Form{ Text * textFilePath; Text * textFileNumber; ProgressBar * progressBar; public: void Button1_Click(){ string filePath = textFilePath->getText(); int number = atoi(textFileNumber->getText.c_str()); FileSpliter spliter(filePath, number, progressBar); spliter.split(); } }; //FileSpliter2.cpp //有什么问题? //违背依赖倒置原则 //不依赖于具体的界面 class IPrgress{ public: virtual void DoProgress(float progressValue) = 0; virtual ~IPrgress(){} }; class FileSpliter{ string m_filePath; int m_fileNumber; //ProgressBar *m_progressBar; //具体通知控件 IPrgress* m_iprogress; //抽象通知机制,最大的重点 public: FileSpliter(const string &filePath, int fileNumber, IPrgress* iprogress): m_filePath(filePath), m_fileNumber(fileNumber), m_iprogress(iprogress){ } void split(){ //1. 读取文件 //2. 分批次想小文件写入 for (int i = 0; i < m_fileNumber; i++){ //... if(NULL != m_iprogress{ float progressValue = m_fileNumber; progressValue = (i + 1) / m_fileNumber; onProgress(progressValue); } } } protected: void onProgress(float value){ if(NULL != m_iprogress{ m_progressBar->DoProgress(progressValue); //更新进度条 } } }; //MainForm2.cpp //需求:增加进度条 //C++支持多继承,推荐一个主继承类,其他都是接口 //MainForm和ProgressBar是一体的 class MainForm : public Form, public IProgress{ Text * textFilePath; Text * textFileNumber; ProgressBar * progressBar; public: void Button1_Click(){ string filePath = textFilePath->getText(); int number = atoi(textFileNumber->getText.c_str()); FileSpliter spliter(filePath, number, this); spliter.split(); } virtual void DoProgress(float progressValue){ progressBar->setValue(value); } }; //FileSpliter3.cpp //有什么问题? //违背依赖倒置原则 //不依赖于具体的界面 class IPrgress{ public: virtual void DoProgress(float progressValue) = 0; virtual ~IPrgress(){} }; class FileSpliter{ string m_filePath; int m_fileNumber; //ProgressBar *m_progressBar; //具体通知控件 List<IPrgress*> m_iprogressList; //抽象通知机制,最大的重点 public: FileSpliter(const string &filePath, int fileNumber, IPrgress* iprogress): m_filePath(filePath), m_fileNumber(fileNumber), m_iprogress(iprogress){ } void split(){ //1. 读取文件 //2. 分批次想小文件写入 for (int i = 0; i < m_fileNumber; i++){ //... if(NULL != m_iprogress{ float progressValue = m_fileNumber; progressValue = (i + 1) / m_fileNumber; onProgress(progressValue); } } } void addIProgress(IPrgress *iprogress){ //attach m_iprogressList.add(iprogress) } void removeIProgress(IPrgress *iprogress){ //detatch m_iprogressList.remove(iprogress) } protected: void onProgress(float value){ //Notify List<IPrgress*>::Iterator itor = m_iprogressList.begin(); while(itor != m_iprogressList.end()) (*itor)->DoProgress(value); } }; //MainForm3.cpp //需求:增加进度条 //C++支持多继承,推荐一个主继承类,其他都是接口 //MainForm和ProgressBar是一体的 class MainForm : public Form, public IProgress{ Text * textFilePath; Text * textFileNumber; ProgressBar * progressBar; public: void Button1_Click(){ string filePath = textFilePath->getText(); int number = atoi(textFileNumber->getText.c_str()); ConsleNotifier cn; FileSpliter spliter(filePath, number); spliter.addIProgress(this); //订阅通知 spliter.addIProgress(&cn); //订阅通知 } virtual void DoProgress(float progressValue){ progressBar->setValue(value); } }; class ConsleNotifier : public IProgress{ public: virtual void DoProgress(float progressValue){ cout<<"."; } };
https://www.bilibili.com/video/BV1kW411P7KS?p=5
//FileSpliter.cppclass FileSpliter{ string m_filePath; int m_fileNumber; public: FileSpliter(const string &filePath, int fileNumber): m_filePath(filePath), m_fileNumber(fileNumber){ } void split(){ //1. 读取文件 //2. 分批次想小文件写入 for (int i = 0; i < m_fileNumber; i++){ //... } }};
//MainForm.cppclass MainForm : public Form{ Text * textFilePath; Text * textFileNumber; public: void Button1_Click(){ string filePath = textFilePath->getText(); int number = atoi(textFileNumber->getText.c_str()); FileSpliter spliter(filePath, number); spliter.split(); }};
//FileSpliter1.cpp//有什么问题?//违背依赖倒置原则class FileSpliter{ string m_filePath; int m_fileNumber; ProgressBar *m_progressBar; //编译时依赖,实现细节 public: FileSpliter(const string &filePath, int fileNumber, ProgressBar *progressBar): m_filePath(filePath), m_fileNumber(fileNumber), m_progressBar(progressBar){ } void split(){ //1. 读取文件 //2. 分批次想小文件写入 for (int i = 0; i < m_fileNumber; i++){ //... if(NULL != m_progressBar{ m_progressBar->setValue((i + 1) / m_fileNumber); //更新进度条 } } }};
//MainForm1.cpp//需求:增加进度条class MainForm : public Form{ Text * textFilePath; Text * textFileNumber; ProgressBar * progressBar;
public: void Button1_Click(){ string filePath = textFilePath->getText(); int number = atoi(textFileNumber->getText.c_str()); FileSpliter spliter(filePath, number, progressBar); spliter.split(); }};
//FileSpliter2.cpp//有什么问题?//违背依赖倒置原则
//不依赖于具体的界面
class IPrgress{public: virtual void DoProgress(float progressValue) = 0; virtual ~IPrgress(){}};
class FileSpliter{ string m_filePath; int m_fileNumber; //ProgressBar *m_progressBar; //具体通知控件 IPrgress* m_iprogress; //抽象通知机制,最大的重点 public: FileSpliter(const string &filePath, int fileNumber, IPrgress* iprogress): m_filePath(filePath), m_fileNumber(fileNumber), m_iprogress(iprogress){ } void split(){ //1. 读取文件 //2. 分批次想小文件写入 for (int i = 0; i < m_fileNumber; i++){ //... if(NULL != m_iprogress{ float progressValue = m_fileNumber; progressValue = (i + 1) / m_fileNumber; onProgress(progressValue); } } }
protected: void onProgress(float value){ if(NULL != m_iprogress{ m_progressBar->DoProgress(progressValue); //更新进度条 } }};
//MainForm2.cpp//需求:增加进度条
//C++支持多继承,推荐一个主继承类,其他都是接口//MainForm和ProgressBar是一体的class MainForm : public Form, public IProgress{ Text * textFilePath; Text * textFileNumber; ProgressBar * progressBar;
public: void Button1_Click(){ string filePath = textFilePath->getText(); int number = atoi(textFileNumber->getText.c_str()); FileSpliter spliter(filePath, number, this); spliter.split(); } virtual void DoProgress(float progressValue){ progressBar->setValue(value); }};
//FileSpliter3.cpp//有什么问题?//违背依赖倒置原则
//不依赖于具体的界面
class IPrgress{public: virtual void DoProgress(float progressValue) = 0; virtual ~IPrgress(){}};
class FileSpliter{ string m_filePath; int m_fileNumber; //ProgressBar *m_progressBar; //具体通知控件 List<IPrgress*> m_iprogressList; //抽象通知机制,最大的重点 public: FileSpliter(const string &filePath, int fileNumber, IPrgress* iprogress): m_filePath(filePath), m_fileNumber(fileNumber), m_iprogress(iprogress){ }
void split(){ //1. 读取文件 //2. 分批次想小文件写入 for (int i = 0; i < m_fileNumber; i++){ //... if(NULL != m_iprogress{ float progressValue = m_fileNumber; progressValue = (i + 1) / m_fileNumber; onProgress(progressValue); } } } void addIProgress(IPrgress *iprogress){ //attach m_iprogressList.add(iprogress) }
void removeIProgress(IPrgress *iprogress){ //detatch m_iprogressList.remove(iprogress) }
protected: void onProgress(float value){ //Notify List<IPrgress*>::Iterator itor = m_iprogressList.begin(); while(itor != m_iprogressList.end()) (*itor)->DoProgress(value); }};
//MainForm3.cpp//需求:增加进度条
//C++支持多继承,推荐一个主继承类,其他都是接口//MainForm和ProgressBar是一体的class MainForm : public Form, public IProgress{ Text * textFilePath; Text * textFileNumber; ProgressBar * progressBar;
public: void Button1_Click(){ string filePath = textFilePath->getText(); int number = atoi(textFileNumber->getText.c_str()); ConsleNotifier cn; FileSpliter spliter(filePath, number);
spliter.addIProgress(this); //订阅通知 spliter.addIProgress(&cn); //订阅通知 } virtual void DoProgress(float progressValue){ progressBar->setValue(value); }};
class ConsleNotifier : public IProgress{public: virtual void DoProgress(float progressValue){ cout<<"."; }};