新版MQL语言程序设计:观察者模式的原理、应用及代码实现

文章目录

    • 一、什么是观察者模式
    • 二、观察者模式的实现原理
    • 三、观察者模式的应用场景
    • 四、观察者模式的代码实现

一、什么是观察者模式

观察者模式是一种行为设计模式,它定义了对象之间的一对多依赖关系,使得当一个对象的状态发生改变时,所有依赖于它的对象都会自动收到通知并更新。在观察者模式中,被观察者(也称为主题)维护一个观察者列表,并提供注册、注销和通知的方法,而观察者则定义了一个更新方法,用于接收被观察者的通知并进行相应的处理。

观察者模式是一种行为设计模式,它定义了对象之间的一对多依赖关系,使得当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。

二、观察者模式的实现原理

  1. 定义主题(Subject)接口:主题是被观察的对象,它需要提供注册、注销和通知观察者的方法。
  2. 实现具体主题(ConcreteSubject)类:具体主题继承自主题接口,并实现注册、注销和通知观察者的方法。它还维护一个观察者列表,用于存储所有注册的观察者。
  3. 定义观察者(Observer)接口:观察者是接收主题通知的对象,它需要提供更新方法,用于在接收到通知时执行相应的操作。
  4. 实现具体观察者(ConcreteObserver)类:具体观察者继承自观察者接口,并实现更新方法。在更新方法中,具体观察者可以获取主题传递的数据,并执行相应的业务逻辑。
  5. 主题状态改变时通知观察者:当主题的状态发生改变时,它会遍历观察者列表,并调用每个观察者的更新方法,将状态改变的信息传递给观察者。

观察者模式的实现原理可简单概括为:主题维护观察者列表,当主题状态改变时,遍历观察者列表并通知观察者进行更新。

三、观察者模式的应用场景

  • GUI事件处理:在图形用户界面中,观察者模式常被用于处理用户界面组件的事件。当用户与界面交互时,触发的事件可以被多个观察者监听和处理。
  • 订阅发布系统:观察者模式可以用于实现订阅发布系统,其中发布者是主题对象,而订阅者是观察者对象。当发布者发布新的消息时,所有订阅者都会收到通知并进行相应的处理。
  • 股票市场监测:在股票市场中,投资者可以作为观察者对象,监听某只股票的价格变化。当股票价格发生变化时,观察者会收到通知并进行相应的投资决策。
  • 消息队列系统:观察者模式可以用于实现消息队列系统,其中生产者是主题对象,而消费者是观察者对象。当生产者产生新的消息时,所有消费者都会收到通知并进行相应的处理。

四、观察者模式的代码实现

//+------------------------------------------------------------------+
//| observer                                                         |
//+------------------------------------------------------------------+
interface Observer
{
    void Update(string state);
};
//+------------------------------------------------------------------+
//| concrete observer                                                |
//+------------------------------------------------------------------+
class ConcreteObserver : public Observer
{
    public:
        void              Update(string state);
        ConcreteObserver(ConcreteSubject& subject);
    protected:
        string            m_observer_state;
        ConcreteSubject  *m_subject;
};
//+------------------------------------------------------------------+
//| constructor                                                      |
//+------------------------------------------------------------------+
ConcreteObserver::ConcreteObserver(ConcreteSubject& subject): m_subject(&subject)
{

}
//+------------------------------------------------------------------+
//| update                                                           |
//+------------------------------------------------------------------+
void ConcreteObserver::Update(string state)
{
    m_observer_state=state;
    Print("observer ",&this," state updated to: ",m_observer_state);
}
//+------------------------------------------------------------------+
//| subject                                                          |
//+------------------------------------------------------------------+
class Subject
{
    public:
        Subject(void);
        ~Subject(void);
        //
        void              Attach(Observer* observer);
        void              Detach(Observer& observer);
        void              Notify(void);
        void              State(string state);
        string            State(void) {return m_state;}
        //
    protected:
        string            m_state;
        // 观察者数组
        Observer         *m_observers[];
        // 查找指定观察者是否在观察者数组中
        int               Find(Observer &observer);
};
//+------------------------------------------------------------------+
//| constructor                                                      |
//+------------------------------------------------------------------+
Subject::Subject(void): m_state(NULL)
{

}
//+------------------------------------------------------------------+
//| destructor                                                       |
//+------------------------------------------------------------------+
Subject::~Subject(void)
{
    int itotal=ArraySize(m_observers);
    for(int i=0; i<itotal; i++)
    {
        Observer* item=m_observers[i];
        //---delete
        if(CheckPointer(item)==1)
        {
            delete item;
        }
    }
}
//+------------------------------------------------------------------+
//| state                                                            |
//+------------------------------------------------------------------+
void Subject::State(string state)
{
    m_state=state;
    Print("subject state set to: ",state);
}
//+------------------------------------------------------------------+
//| notify                                                           |
//+------------------------------------------------------------------+
void Subject::Notify(void)
{
    int itotal=ArraySize(m_observers);
    for (int i=0; i<itotal; i++)
    {
        Print("pushing state to observer ",m_observers[i],"...");
        m_observers[i].Update(m_state);
    }
}
//+------------------------------------------------------------------+
//| attach                                                           |
//+------------------------------------------------------------------+
void Subject::Attach(Observer *observer)
{
    int size=ArraySize(m_observers);
    ArrayResize(m_observers,size+1);
    m_observers[size]=observer;
}
//+------------------------------------------------------------------+
//| detach                                                           |
//+------------------------------------------------------------------+
void Subject::Detach(Observer &observer)
{
    int find=Find(observer);
    if(find==-1)
        return;
    Observer* item=m_observers[find];
    //---delete
    if(CheckPointer(item)==1)
        delete item;
    ArrayRemove(m_observers,find,1);
}
//+------------------------------------------------------------------+
//| find                                                             |
//+------------------------------------------------------------------+
int Subject::Find(Observer &observer)
{
    int itotal=ArraySize(m_observers);
    for(int i=0; i<itotal; i++)
    {
        Observer* item=m_observers[i];
        if(item==&observer)
            return i;
    }
    return -1;
}
//+------------------------------------------------------------------+
//| concrete subject                                                 |
//+------------------------------------------------------------------+
class ConcreteSubject:public Subject
{

};
//+------------------------------------------------------------------+
//| client                                                           |
//+------------------------------------------------------------------+
void OnStart(void)
{
    ConcreteSubject subject;
    subject.Attach(new ConcreteObserver(subject));
    subject.Attach(new ConcreteObserver(subject));
    subject.State("new push state");
    subject.Notify();
}

你可能感兴趣的:(新版MQL语言程序设计,观察者模式,设计模式,学习,笔记,MT4,MT5,MQL)