1

我正在 Qt 中开发 GUI 表单,我想知道如何实现 ObserverPattern。表单可以订阅由tickerId区分的许多数据流,当数据流到达(新报价可用)时,我的PosixClient(套接字包装器)触发notifyObservers()方法导致update()观察者方法被执行。

但:

这种update()方法是void update(),我需要获取传入的数据记录并绘制它们,计算一些东西,然后使用它们。那么我该如何实现这一点,如何将数据记录传递给观察者呢?数据可用于 Observable(MarketData 对象派生自 Observable)。当数据到达时,我将其推送到这个 Observable 并通知观察者。

void PosixClient::tickPrice( TickerId tickerId, TickType field, double price, int canAutoExecute) {
    printf("tradingclient_1: tickPrice: \n");
    for(std::vector<boost::shared_ptr<MarketData> >::iterator it=dataRepository.begin(); 
            it!=dataRepository.end(); it++){
        if((*it)->tickerId==tickerId){
            (*it)->tickPriceData.push_back(tickSizeRecord(field,price,canAutoExecute));
            (*it)->notifyObservers();
            //TODO: start thread to store incoming data in repository
        }
    }
}

然后调用他们的void update()方法。为了从这个函数中检索数据,我决定将一个函数指针boost::function<>作为回调传递给它,然后 Observer 调用这个函数指针,该指针指向我的 GUI 对象,并将来自 observable 的传入数据作为参数。这是正确的方法吗?

struct MarketData : public QuantLib::Observable {
//public:
    MarketData();
    MarketData(IB::Contract c, int tickerId):c(c),tickerId(tickerId){}
    MarketData(const MarketData& orig);
    virtual ~MarketData();
    std::vector<IB::Record> tickPriceData; //market data fed in tickPrice
//private:
    IB::Contract c;
    int tickerId;
};

typedef boost::shared_ptr<MarketData> pMyObservable;
typedef boost::function<void (int tickerId, IB::Record record)> f_action_ptr;

class MarketDataObserver : public QuantLib::Observer{
public:
    MarketDataObserver(pMyObservable obs, f_action_ptr ptr)
        : observable(obs), f_ptr(ptr){
      this->registerWith(observable);
    }
    MarketDataObserver(const MarketDataObserver &observer)
      : Observer(observer),
        observable(observer.observable){ // faction_ptr is not copied!
    }

    void update(){
        data=observable->tickPriceData.back();
        //printf("new data: %l\n",data.price);
        f_ptr(observable->tickerId, data);
    }
private:
    IB::Record data;
    pMyObservable observable;
    f_action_ptr f_ptr;
};

请注意:

我知道 Qt 信号/插槽机制,但在我看来,Qt 信号/插槽根本不是解决方案,当我需要动态订阅数据时,绘制它们,在 Qt Form 上显示,然后在取消 Form 时删除订阅。但也许我错了。我是吗?我要求来自生活的真实的、有效的例子,而不是理论上的争论。

4

1 回答 1

1

观察者模式的常用 Qt 习语确实是信号和插槽。让数据源发出信号并将数据作为信号的参数传递。这就是在 Qt 中完成的方式——信号不仅仅用于 GUI 事件。

于 2013-05-27T16:58:01.507 回答