observer container

folly中的ObserverContainer实现了观察者模式

#include <folly/init/Init.h>
#include <folly/ObserverContainer.h>
#include <iostream>
//subject触发的事件
enum class TestObserverEvents : uint8_t { SpecialEvent = 1, SuperSpecialEvent = 2 };

//模板参数8代表observerContainer初始reserve的大小
using TestObserverContainerPolicy = folly::ObserverContainerBasePolicyDefault<TestObserverEvents, 8>;

//observer的接口
template <typename ObservedT>
class TestObserverInterface
{
 public:
  virtual ~TestObserverInterface() = default;
  virtual void special(ObservedT*) noexcept {}
  virtual void superSpecial(ObservedT*) noexcept {}
  virtual void broadcast(ObservedT*) noexcept {}
};

//subject本身,存有ObserverContainer对象
class TestSubject
{
 public:
 //构造函数中初始化observercontainer
  TestSubject() : observerCtr(this) {}
  using ObserverContainer =
      folly::ObserverContainer<TestObserverInterface<TestSubject>, TestSubject, TestObserverContainerPolicy>;

  //object special动作触发special事件
  void doSomethingSpecial()
  {
    observerCtr.invokeInterfaceMethod<TestObserverEvents::SpecialEvent>(
        [](auto observer, auto observed) { observer->special(observed); });
  }

  void doSomethingSuperSpecial()
  {
    observerCtr.invokeInterfaceMethod<TestObserverEvents::SuperSpecialEvent>(
        [](auto observer, auto observed) { observer->superSpecial(observed); });
  }

   //object broadcast动作广播触发所有事件。
  void doBroadcast()
  {
    observerCtr.invokeInterfaceMethodAllObservers([](auto observer, auto observed) { observer->broadcast(observed); });
  }

  ObserverContainer observerCtr;
};

template <typename ObserverContainerT>
class ManagedObserverToTestObj : public ObserverContainerT::ManagedObserver
{
 public:
  using TestSubjectT = typename ObserverContainerT::observed_type;
  using ObserverContainerBase =
      folly::ObserverContainerBase<TestObserverInterface<typename ObserverContainerT::observed_type>,
                                   typename ObserverContainerT::observed_type, TestObserverContainerPolicy>;
  using EventEnum       = typename ObserverContainerT::EventEnum;
  using EventSet        = typename TestSubjectT::ObserverContainer::Observer::EventSet;
  using EventSetBuilder = typename TestSubjectT::ObserverContainer::Observer::EventSetBuilder;

  using ObserverContainerT::ManagedObserver::ManagedObserver;


 private:
 //observer实现各种事件对应的接口
  void special(TestSubjectT* obj) noexcept override { std::cout << "observed special\n"; }
  void superSpecial(TestSubjectT* obj) noexcept override { std::cout << "observed special\n"; }
  void broadcast(TestSubjectT* obj) noexcept override { std::cout << "observed boardcast\n"; }
};

void testObserver()
{
  using MockManagedObserver = ManagedObserverToTestObj<TestSubject::ObserverContainer>;
  {
    std::cout << "----\n";
    //创建一个observer,
       //managedobserver的析构函数会使subject的observerCtr remove掉managedobserber本身,线程不安全
       //一个managedobserver应只观察一个subject,
    auto observer1 =
        std::make_unique<MockManagedObserver>(MockManagedObserver::EventSetBuilder().enableAllEvents().build());
        //注册 observer
    obj1->observerCtr.addObserver(observer1.get());
    //所有的observer的数量
    std::cout << obj1->observerCtr.numObservers() << std::endl;
    //所有的observer的数量
    std::cout << obj1->observerCtr.getObservers().size() << std::endl;
    //所有的observer的数量
    std::cout << obj1->observerCtr.findObservers().size() << std::endl;
    //TestSubject::ObserverContainer::Observer的observer的数量,也就是所有的数量
    std::cout << obj1->observerCtr.findObservers<TestSubject::ObserverContainer::Observer>().size() << std::endl;

    //MockManagedObserver的数量
    std::cout << obj1->observerCtr.findObservers<MockManagedObserver>().size() << std::endl;
    std::cout << "----\n";
    //subject动作,从而触发各种事件
    obj1->doSomethingSuperSpecial();
    obj1->doSomethingSpecial();
    obj1->doBroadcast();
  }
}

int main(int argc, char** argv)
{
  folly::init(&argc, &argv);
  testObserver();
}
Posted 2023-05-16