zoukankan      html  css  js  c++  java
  • 观察者模式

    在软件实现过程中,一个对象的状态发生改变所依赖的对象都须得到通知需要通知,但这种依赖不能过于紧密,需要抵御变化,

    通过实现进度条的伪码来实现

    该MainForm1.cpp中通过实现具体的进度条代码,来达到需求,如果需求改变,则需要在源码中所需位置依次增加所需代码

    MainForm1.cpp

     1 class MainForm : public Form                                                  
     2 {
     3     TextBox* txtFilePath;
     4     TextBox* txtFileNumber;
     5     ProgressBar* progressBar;
     6 
     7 public:
     8     void Button1_Click(){
     9 
    10         string filePath = txtFilePath->getText();
    11         int number = atoi(txtFileNumber->getText().c_str());
    12 
    13         FileSplitter splitter(filePath, number, progressBar);
    14 
    15         splitter.split();
    16 
    17     }  
    18 };

    FileSplitter1.cpp

     1 class FileSplitter                                                            
     2 {
     3     string m_filePath;
     4     int m_fileNumber;
     5     ProgressBar* m_progressBar;
     6 
     7 public:
     8     FileSplitter(const string& filePath, int fileNumber, ProgressBar* progressBar) :
     9         m_filePath(filePath), 
    10         m_fileNumber(fileNumber),
    11         m_progressBar(progressBar){
    12 
    13     }  
    14 
    15     void split(){
    16 
    17         //1.读取大文件
    18 
    19         //2.分批次向小文件中写入
    20         for (int i = 0; i < m_fileNumber; i++){
    21             //...
    22             float progressValue = m_fileNumber;
    23             progressValue = (i + 1) / progressValue;
    24             m_progressBar->setValue(progressValue);
    25         }  
    26 
    27     }  
    28 };

    MainForm2.cpp

    class MainForm : public Form, public IProgress                                
    {
        TextBox* txtFilePath;
        TextBox* txtFileNumber;
    
        ProgressBar* progressBar;
    
    public:
        void Button1_Click(){
    
            string filePath = txtFilePath->getText();
            int number = atoi(txtFileNumber->getText().c_str());
    
            ConsoleNotifier cn;
    
            FileSplitter splitter(filePath, number);
    
            splitter.addIProgress(this); //订阅通知
            splitter.addIProgress(&cn); //订阅通知
    
            splitter.split();
    
            splitter.removeIProgress(this);
    
        }  
    
        virtual void DoProgress(float value){
            progressBar->setValue(value);
        }  
    };
    
    class ConsoleNotifier : public IProgress {
    public:
        virtual void DoProgress(float value){
            cout << ".";
        }  
    };

    通过在父类中声明一个纯虚函数,以指针的形式实现多态可以通过不同的数据结构实现多个通知,可根据各种不同需求在子类中(DoProgress())中实现具体的功能。

    FileSplitter2.cpp

     1 class IProgress{                                                              
     2 public:
     3     virtual void DoProgress(float value)=0;
     4     virtual ~IProgress(){}
     5 };
     6 
     7 
     8 class FileSplitter
     9 {
    10     string m_filePath;
    11     int m_fileNumber;
    12 
    13     List<IProgress*>  m_iprogressList; // 抽象通知机制,支持多个观察者
    14     
    15 public:
    16     FileSplitter(const string& filePath, int fileNumber) :
    17         m_filePath(filePath), 
    18         m_fileNumber(fileNumber){
    19 
    20     }  
    21 
    22 
    23     void split(){
    24 
    25         //1.读取大文件
    26 
    27         //2.分批次向小文件中写入
    28         for (int i = 0; i < m_fileNumber; i++){
    29             //...
    30 
    31             float progressValue = m_fileNumber;
    32             progressValue = (i + 1) / progressValue;
    33             onProgress(progressValue);//发送通知
    34         }  
    35 
    36     }  
    37 
    38 
    39     void addIProgress(IProgress* iprogress){
    40         m_iprogressList.push_back(iprogress);
    41     }  
    42 
    43     void removeIProgress(IProgress* iprogress){
    44         m_iprogressList.remove(iprogress);
    45     }  
    46 
    47 
    48 protected:
    49     virtual void onProgress(float value){
    50     
    51         List<IProgress*>::iterator itor=m_iprogressList.begin();
    52 
    53         while (itor != m_iprogressList.end() )
    54             (*itor)->DoProgress(value); //更新进度条
    55             itor++;
    56         }  
    57     }  
    58 };

    单继承一个父类,多继承其他接口

    不推荐大括号换行,这个增加了语法分析时间复杂度,扫描时要去掉回车换行符

  • 相关阅读:
    模拟——1031D
    线性dp——cf1032
    莫比乌斯反演——专题练习
    数论,质因数,gcd——cf1033D 好题!
    连通图,set——cf1037E
    线段树动态开点——cf1045G
    跳表上线性dp——1150D 好题!
    高斯消元求主元——模意义下的消元cf1155E
    汽车长期停放,毁车没商量?
    驾校都是错的?这才是日常驾驶正确的换挡方式
  • 原文地址:https://www.cnblogs.com/miaorn/p/14387234.html
Copyright © 2011-2022 走看看