1. 程式人生 > 實用技巧 >Design Patterns 5 - 觀察者模式 Observer

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<<"."; }};