C++设计模式04 —— 观察者模式

发布时间 2024-01-10 15:27:13作者: Torch_HXM

观察者模式

  • 一种一对多的依赖关系,当被依赖的对象发生改变时,所有依赖它的对象都能够做出相应的改变。

  • 为一个文件分割器加入进度展示。我们需要支持多个类型的进度条,我们可以随意操控进度条的样式细节。


首先,我们做一个进度条的抽象基类

class IProgress{
public:
    virtual void DoProgress(float value)=0;
    virtual ~IProgess(){};
};

在文件分割器中,我们有一个进度条的列表,并支持添加和删除进度条。

class FileSpliter{
public:
    FileSpliter(const string& filePath, int fileNumber, IProgress* progressbar):m_filePath(filePath),m_fileNumber(fileNumber){}
    void splite(){
        // 读取文件

        // 分批次向文件中写入
        for(int i=0;i<m_fileNumber;i++){
            // ...
            onProgress(float(i+1)/m_fileNumber);
        }
    }

    void addProgressBar(IProgress* progressBar){
        progressBarList.push_back(progressBar);
    }

    void removeProgressBar(IProgress* progressBar){
        progressBarList.remove(progressBar);
    }

    void onProgress(float value){
        for(auto progressBar:progressBarList){
            progressBar->DoProgress(value);
        }
    }

private:
    string m_filePath;
    int m_fileNumber;
    vector<IProgress*> progressBarList;
};

最后,在主程序中,我们可以自由添加进度条,并定义进度条的实现细节

class   OtherProgressBar:public IProgress{
public:
    virtual void DoProgress(float value){
        // ...
    }
};

class MainWindow:public Window, public IProgress{
private:
    // ...
public:
    virtual void DoProgress(float value){
        // ...
    }
    
    void main(){
        // ...

        FileSpliter spliter(filePath, number);

        OtherProgressBar pb;

        spliter.addProgressBar(this);
        spliter.addProgressBar(&pb);
    }
    
};

观察者模式,让进度条和主程序之间解耦,我可以随意的添加减少进度条,并随意的修改进度条的实现细节。

观察者无需指定进度条,进度条自己决定自己是否加入到进度条队列中。