Observe观察者模式

动机(Motivation)

  • 在软件构建过程中,我们需要为某些对象建立一种“通知依赖关系”,——一个对象(目标对象)的状态发生改变,所有依赖对象(观察者对象)都将得到通知,如果这样的依赖关系过于紧密,将是软件不能很好地抵御变化。
  • 使用面向对象技术,可以将这种依赖关系弱化,并形成一种稳定的依赖关系,从而实现软件结构的松耦合。

code

FileSplitter.cpp

class FileSplitter 
{
    string m_filePath;
    int m_fileNumber;

public:
    FileSplitter(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
{
    TextBox* txtFilePath;
    TexBox* texFileNumber;

public:
    void Button1_Click() {
        string txtPath = txtFilePath->getText();
        int number = atol(texFileNumber->getText().c_str());

        FileSplitter splitter(filePath, number);
        splitter.split();
    }
};

 上述代码存在的问题:

  1.   比如说需求变化,用户希望加一个进度条,来进行进度展示

修改后的代码:

FileSplitter.cpp

class FileSplitter 
{
    string m_filePath;
    int m_fileNumber;
    ProgessBar* m_progessBar;

public:
    FileSplitter(const string& filePath, int fileNumber, 
        ProgessBar* progessBar) :
        m_filePath(filePath), 
        m_fileNumber(fileNumber),
        m_progessBar(progessBar)
    {
        //...
    }

    void split()
    {
        //1.读取大文件

        //2.分批次向小文件中写入
        for (int i = 0; i < m_fileNumber; i++)
        {
            //..
            if (m_progessBar != nullptr)
            {
                m_progessBar->setValue((i + 1) / m_fileNumber);//更新进度条
            }
            
        }
    }
};

  mainForm.cpp

class MainForm :public Form
{
    TextBox* txtFilePath;
    TexBox* texFileNumber;
    ProgessBar* progessBar;

public:
    void Button1_Click() {
        string txtPath = txtFilePath->getText();
        int number = atol(texFileNumber->getText().c_str());

        FileSplitter splitter(filePath, number, progessBar);
        splitter.split();
    }
};

  存在的问题点:

         违背的依赖倒置的原则,依赖具体实现细节。

继续修改

FileSplitter.cpp

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


class FileSplitter
{
    string m_filePath;
    int m_fileNumber;
    //ProgessBar* m_progessBar;
    List<Iprogress*> *m_iprogessList; //抽象通知机制,支持多个观察者

public:
    FileSplitter(const string& filePath, int fileNumber) :
        m_filePath(filePath),
        m_fileNumber(fileNumber)

    {
        //...
    }

    void add_IProgess(IProgess * iprogress){
        m_iprogessList.push_back(iprogress);
    }

    void remove_IProgess(IProgess * iprogress) {
        m_iprogessList.remove(iprogress);
    }

    void split()
    {
        //1.读取大文件

        //2.分批次向小文件中写入
        for (int i = 0; i < m_fileNumber; i++)
        {
            //..
            float progressValue = m_fileNumber;
            progressValue = (i + 1) / m_fileNumber;
            onProcess(progressValue);
        }
    }
protected:
    void onProcess(float value) {

        List<IProgess*>::Iterator itor = m_iprogessList.begin();

        while (itor != m_iprogessList.end()
        {
            m_iprogessList->DoProgess(progressValue);//更新进度条
            itor++;
        }
    }
}
};

mainForm.cpp

class MainForm :public Form, public IProgess
{
    TextBox* txtFilePath;
    TexBox* texFileNumber;
    ProgessBar* progessBar;

public:
    void Button1_Click() {
        string txtPath = txtFilePath->getText();
        int number = atol(texFileNumber->getText().c_str());

        FileSplitter splitter(filePath, number);
        splitter.add_IProgess(this);
        splitter.add_IProgess(&cn);
        splitter.split();

        splitter.remove_IProgess(this);
    }

    virtual void DoProgress(float value) {
        progessBar->setValue(value)
    }
};

class ConsoleNotifer :public IProgess {
public:
    virtual void DoProgress(float value) {
        cout << ".";
    }
};

 

转载于:https://www.cnblogs.com/malloc1free/p/11119586.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值