c – 如何在Observer中处理具有不同状态值类型的Observable

前端之家收集整理的这篇文章主要介绍了c – 如何在Observer中处理具有不同状态值类型的Observable前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
(上下文和问题,帖子底部的骨架代码)

我们正在创建和实现一个在Arduino等环境中使用的C框架.

为此,我想使用Observer模式,其中任何对传感器状态变化感兴趣的组件(Observables)都可以注册自己,Observable会通过调用Observer的notification()方法将其自身作为一个变更通知.参数.

一个观察者可以观察到多个Observable,反之亦然.

问题在于Observer需要提取Observable的当前状态并对其执行某些操作,并且此当前状态可以采用所有形式和大小,具体取决于Observable的特定传感器.

它当然可以是序数值,它们是有限的并且可以编码出来,就像我在下面的代码中用方法getValueasInt()所做的那样,但它也可以是传感器特定的结构,即对于RealTimeClock,它提供了一个结构日期和时间值.结构当然在编译时定义,并针对特定传感器进行修复.

我的问题:什么是最优雅,未来修改解决方案或模式?

编辑:请注意,dynamic_cast<>由于Arduino的限制,结构是不可能的

我创建了以下类层次结构(框架代码):

class SenseNode
{
public:
  SenseNode() {};
  SenseNode(uint8_t aNodeId): id(aNodeId) {}
  virtual ~SenseNode() {}

  uint8_t getId() { return id; };
private:
  uint8_t id = 0;
};

class SenseStateNode : virtual public SenseNode
{
public:
  SenseStateNode(uint8_t aNodeId) : SenseNode(aNodeId) {}
  virtual ~SenseStateNode() {}

  /** Return current node state interpreted as an integer. */
  virtual int getValueAsInt();
};

class SenSEObservable: public SenseStateNode
{
public:
  SenSEObservable(uint8_t aNodeId);
  virtual ~SenSEObservable();
  /** Notify all interested observers of the change in state by calling Observer.notification(this) */
  virtual void notifyObservers();
protected:
  virtual void registerObserver(SenSEObserver *);
  virtual void unregisterObserver(SenSEObserver *);
};

class SenSEObserver: virtual public SenseNode
{
public:
  SenSEObserver() {};
  virtual ~SenSEObserver();

  /** Called by an Observable that we are observing to inform us of a change in state */
  virtual void notification(SenSEObservable *observable) {
    int v = observable->getValueAsInt(); // works like a charm
    DateTime d = observable-> ????  // How should i solve this elegantly?
  };
};

解决方法

如果传感器类型的数量或多或少稳定(并且它是 – 在大多数情况下变化非常罕见) – 那么只需在Observer端准备以获得几种通知
class Observer 
{
public:
     virtual void notify(SenseNode& node) {
        // implement here general actions - like printing: not interested in this

     } 
     virtual void notify(RealTimeClock& node) {
          notify(static_cast<SenseNode&>(node)); 
         // by default go to more general function
     } 
     // and follow this pattern - for all nodes you want to handle
     // add corresponding notify(T&) function
};

当它发生时你必须添加新的节点类型 – 然后只需将新的虚函数添加到你的基础Observer类.

要在Observable端实现此机制 – 使用double dispatch pattern

class SenseNode {
public:
    virtual void notifyObserver(Observer& observer) {
       observer.notify(*this);
    }
};

class RealTimeClock : public virtual SenseNode {
public:
    virtual void notifyObserver(Observer& observer) {
       observer.notify(*this); 
        // this will select proper Observer::notify(RealTimeClock&)
        // because *this is RealTimeCLock
    }
};


class SenSEObservable: public SenseStateNode
{
public:
  virtual void notifyObservers() {
      for (auto& observer : observers) 
         notifyObserver(observer); 
  }
};

它在实践中如何运作,见live demo

猜你在找的C&C++相关文章